Improve fuzz testing to find string scan bug
This commit is contained in:
1
corpus/example.bin
Normal file
1
corpus/example.bin
Normal file
@@ -0,0 +1 @@
|
|||||||
|
"<22> <20> "
|
||||||
56
src/fuzz.cpp
56
src/fuzz.cpp
@@ -42,6 +42,25 @@ std::pair<std::string, WeaselJsonStatus> runBatch(std::string copy) {
|
|||||||
return {state.result, s};
|
return {state.result, s};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<std::string, WeaselJsonStatus> runPrefix(std::string copy,
|
||||||
|
int prefix) {
|
||||||
|
SerializeState state;
|
||||||
|
auto c = serializeCallbacks();
|
||||||
|
std::unique_ptr<WeaselJsonParser, decltype(&WeaselJsonParser_destroy)> parser{
|
||||||
|
WeaselJsonParser_create(1024, &c, &state), WeaselJsonParser_destroy};
|
||||||
|
auto s = WeaselJsonParser_parse(parser.get(), copy.data(), prefix);
|
||||||
|
if (s != WeaselJson_AGAIN) {
|
||||||
|
return {state.result, s};
|
||||||
|
}
|
||||||
|
s = WeaselJsonParser_parse(parser.get(), copy.data() + prefix,
|
||||||
|
copy.size() - prefix);
|
||||||
|
if (s != WeaselJson_AGAIN) {
|
||||||
|
return {state.result, s};
|
||||||
|
}
|
||||||
|
s = WeaselJsonParser_parse(parser.get(), nullptr, 0);
|
||||||
|
return {state.result, s};
|
||||||
|
}
|
||||||
|
|
||||||
void testStreaming(std::string const &json) {
|
void testStreaming(std::string const &json) {
|
||||||
auto batch = runBatch(json);
|
auto batch = runBatch(json);
|
||||||
if (batch.second == WeaselJson_AGAIN) {
|
if (batch.second == WeaselJson_AGAIN) {
|
||||||
@@ -57,15 +76,36 @@ void testStreaming(std::string const &json) {
|
|||||||
bool batchOk = batch.second == WeaselJson_OK;
|
bool batchOk = batch.second == WeaselJson_OK;
|
||||||
if (streamingOk == batchOk && !batchOk) {
|
if (streamingOk == batchOk && !batchOk) {
|
||||||
// It's ok if the processed data doesn't match if parsing failed
|
// It's ok if the processed data doesn't match if parsing failed
|
||||||
continue;
|
} else {
|
||||||
|
printf("streaming: %s, %s\n",
|
||||||
|
streaming.second == WeaselJson_OK ? "accept" : "reject",
|
||||||
|
streaming.first.c_str());
|
||||||
|
printf("batch: %s, %s\n",
|
||||||
|
batch.second == WeaselJson_OK ? "accept" : "reject",
|
||||||
|
batch.first.c_str());
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (int(json.size()) > stride) {
|
||||||
|
auto prefix = runPrefix(json, stride);
|
||||||
|
if (prefix != batch) {
|
||||||
|
if (prefix.second == WeaselJson_AGAIN) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
bool prefixOk = prefix.second == WeaselJson_OK;
|
||||||
|
bool batchOk = batch.second == WeaselJson_OK;
|
||||||
|
if (prefixOk == batchOk && !batchOk) {
|
||||||
|
// It's ok if the processed data doesn't match if parsing failed
|
||||||
|
} else {
|
||||||
|
printf("prefix: %s, %s\n",
|
||||||
|
prefix.second == WeaselJson_OK ? "accept" : "reject",
|
||||||
|
prefix.first.c_str());
|
||||||
|
printf("batch: %s, %s\n",
|
||||||
|
batch.second == WeaselJson_OK ? "accept" : "reject",
|
||||||
|
batch.first.c_str());
|
||||||
|
abort();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
printf("streaming: %s, %s\n",
|
|
||||||
streaming.second == WeaselJson_OK ? "accept" : "reject",
|
|
||||||
streaming.first.c_str());
|
|
||||||
printf("batch: %s, %s\n",
|
|
||||||
batch.second == WeaselJson_OK ? "accept" : "reject",
|
|
||||||
batch.first.c_str());
|
|
||||||
abort();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user