Make the chunk parser stop after trailer, trigger next bug to fix
This commit is contained in:
+7
-10
@@ -84,6 +84,9 @@ namespace uWS {
|
|||||||
|
|
||||||
if (chunkSize(state) == 0) {
|
if (chunkSize(state) == 0) {
|
||||||
state = 0;
|
state = 0;
|
||||||
|
|
||||||
|
/* The parser MUST stop consuming here */
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -146,15 +149,12 @@ namespace uWS {
|
|||||||
/* This is really just a wrapper for convenience */
|
/* This is really just a wrapper for convenience */
|
||||||
struct ChunkIterator {
|
struct ChunkIterator {
|
||||||
|
|
||||||
std::string_view data;
|
std::string_view *data;
|
||||||
std::optional<std::string_view> chunk;
|
std::optional<std::string_view> chunk;
|
||||||
unsigned int *state;
|
unsigned int *state;
|
||||||
|
|
||||||
ChunkIterator(std::string_view data, unsigned int *state) : data(data), state(state) {
|
ChunkIterator(std::string_view *data, unsigned int *state) : data(data), state(state) {
|
||||||
chunk = uWS::getNextChunk(this->data, *state);
|
chunk = uWS::getNextChunk(*data, *state);
|
||||||
if (!chunk && this->data.length()) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChunkIterator() {
|
ChunkIterator() {
|
||||||
@@ -181,10 +181,7 @@ namespace uWS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ChunkIterator &operator++() {
|
ChunkIterator &operator++() {
|
||||||
chunk = uWS::getNextChunk(data, *state);
|
chunk = uWS::getNextChunk(*data, *state);
|
||||||
if (!chunk && this->data.length()) {
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,18 +30,28 @@ void runTest(unsigned int maxConsume) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::string buffer = ss.str();
|
std::string buffer = ss.str();
|
||||||
|
|
||||||
|
/* Since we have 2 chunked bodies in our buffer, the parser must stop with state == 0 exactly 2 times */
|
||||||
|
unsigned int stoppedWithClearState = 0;
|
||||||
|
|
||||||
/* Begin with a clear state and the full data */
|
/* Begin with a clear state and the full data */
|
||||||
unsigned int state = 0;
|
unsigned int state = 0;
|
||||||
unsigned int chunkOffset = 0;
|
unsigned int chunkOffset = 0;
|
||||||
std::string_view chunkEncoded = buffer;
|
std::string_view chunkEncoded = buffer;
|
||||||
|
|
||||||
|
// this while should be more like if original size or "is parsing chunked" (which tests the uWS::wantsChunkedParsing(state))
|
||||||
while (chunkEncoded.length()) {
|
while (chunkEncoded.length()) {
|
||||||
/* Parse a small part of the given data */
|
/* Parse a small part of the given data */
|
||||||
std::string_view data = chunkEncoded.substr(0, std::min<size_t>(maxConsume, chunkEncoded.length()));
|
std::string_view data = chunkEncoded.substr(0, std::min<size_t>(maxConsume, chunkEncoded.length()));
|
||||||
chunkEncoded.remove_prefix(data.length());
|
|
||||||
|
|
||||||
|
unsigned int data_length_before_parsing = data.length();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Whatever chunk we emit, or part of chunk, it must match the expected one */
|
/* Whatever chunk we emit, or part of chunk, it must match the expected one */
|
||||||
for (auto chunk : uWS::ChunkIterator(data, &state)) {
|
//std::cout << "Calling parser now" << std::endl;
|
||||||
|
for (auto chunk : uWS::ChunkIterator(&data, &state)) {
|
||||||
std::cout << "<" << chunk << ">" << std::endl;
|
std::cout << "<" << chunk << ">" << std::endl;
|
||||||
|
|
||||||
/* Run check here */
|
/* Run check here */
|
||||||
@@ -60,13 +70,27 @@ void runTest(unsigned int maxConsume) {
|
|||||||
std::abort();
|
std::abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* The parser returtned, okay count the times it has state == 0, it should be 2 per the whole buffer always */
|
||||||
|
if (state == 0) {
|
||||||
|
printf("Parser stopped with no state set!\n");
|
||||||
|
stoppedWithClearState++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only remove that which was consumed */
|
||||||
|
chunkEncoded.remove_prefix(data_length_before_parsing - data.length());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stoppedWithClearState != 2) {
|
||||||
|
std::cerr << "Error: The parser stopped with no state " << stoppedWithClearState << " times!" << std::endl;
|
||||||
|
std::abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
for (int i = 1; i < 1000; i++) {
|
//for (int i = 1; i < 1000; i++) {
|
||||||
runTest(i);
|
runTest(1);
|
||||||
}
|
//}
|
||||||
|
|
||||||
std::cout << "ALL BRUTEFORCE DONE" << std::endl;
|
std::cout << "ALL BRUTEFORCE DONE" << std::endl;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user