diff --git ext/yahttp/yahttp/reqresp.cpp ext/yahttp/yahttp/reqresp.cpp index a96def6e0..9729e2005 100644 --- ext/yahttp/yahttp/reqresp.cpp +++ ext/yahttp/yahttp/reqresp.cpp @@ -173,24 +173,27 @@ namespace YaHTTP { if (pos > 99) throw ParseError("Impossible chunk_size"); buffer.copy(buf, pos); buf[pos]=0; // just in case... buffer.erase(buffer.begin(), buffer.begin()+pos+1); // remove line from buffer - if (sscanf(buf, "%x", &chunk_size) != 1) { + if (sscanf(buf, "%zx", &chunk_size) != 1) { throw ParseError("Unable to parse chunk size"); } if (chunk_size == 0) { state = 3; break; } // last chunk - if (chunk_size > (std::numeric_limits::max() - 2)) { + if (chunk_size > (std::numeric_limits::max() - 2) || chunk_size > maxbody) { throw ParseError("Chunk is too large"); } } else { int crlf=1; - if (buffer.size() < static_cast(chunk_size+1)) return false; // expect newline + if (buffer.size() < chunk_size+1) return false; // expect newline if (buffer.at(chunk_size) == '\r') { - if (buffer.size() < static_cast(chunk_size+2) || buffer.at(chunk_size+1) != '\n') return false; // expect newline after carriage return + if (buffer.size() < chunk_size+2 || buffer.at(chunk_size+1) != '\n') return false; // expect newline after carriage return crlf=2; } else if (buffer.at(chunk_size) != '\n') return false; + if (bodybuf.str().length() + chunk_size > maxbody) { + throw ParseError("Chunked body is too large"); + } std::string tmp = buffer.substr(0, chunk_size); buffer.erase(buffer.begin(), buffer.begin()+chunk_size+crlf); bodybuf << tmp; chunk_size = 0; if (buffer.size() == 0) break; // just in case diff --git ext/yahttp/yahttp/reqresp.hpp ext/yahttp/yahttp/reqresp.hpp index 4db53bec8..e4ea8319c 100644 --- ext/yahttp/yahttp/reqresp.hpp +++ ext/yahttp/yahttp/reqresp.hpp @@ -298,11 +298,11 @@ public: int state; //