Improve fuzz testing to find string scan bug

This commit is contained in:
2025-06-22 23:00:34 -04:00
parent 5a74124cae
commit 95250d1668
2 changed files with 49 additions and 8 deletions

1
corpus/example.bin Normal file
View File

@@ -0,0 +1 @@
"<22> <20> "

View File

@@ -42,6 +42,25 @@ std::pair<std::string, WeaselJsonStatus> runBatch(std::string copy) {
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) {
auto batch = runBatch(json);
if (batch.second == WeaselJson_AGAIN) {
@@ -57,8 +76,7 @@ void testStreaming(std::string const &json) {
bool batchOk = batch.second == WeaselJson_OK;
if (streamingOk == batchOk && !batchOk) {
// 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());
@@ -68,6 +86,28 @@ void testStreaming(std::string const &json) {
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();
}
}
}
}
}
void compareWithSimdjson(std::string const &json) {