MCPcopy Create free account
hub / github.com/buger/jsonparser / checkParseStringGate

Function checkParseStringGate

json_fuzz_test.go:1159–1205  ·  view source on GitHub ↗

checkParseStringGate (Gate 8: PARSESTRING) extracts a String-typed value via Get and calls ParseString on the raw escaped content. Closes the API- coverage blind spot: without this gate, the structure-aware fuzzer NEVER reaches ParseString on grammar-generated escape sequences (\uXXXX, \uD800\uDC00

(t *testing.T, data []byte, path []string)

Source from the content-addressed store, hash-verified

1157// surrogate pairs, \u0000, long escape runs). It also cross-checks the
1158// unescaped result against encoding/json on the same token.
1159func checkParseStringGate(t *testing.T, data []byte, path []string) {
1160 t.Helper()
1161 if len(data) > fuzzGateSizeCap {
1162 return
1163 }
1164 val, dt, _, err := Get(data, path...)
1165 if err != nil || dt != String || len(val) == 0 {
1166 return
1167 }
1168 out, perr := ParseString(val)
1169 if perr != nil {
1170 // ParseString rejects malformed escapes; that is a clean failure.
1171 return
1172 }
1173 // NOTE: jsonparser is documented as lenient on raw invalid UTF-8 bytes
1174 // inside strings — it passes them through unchanged (consistent with
1175 // Get's no-validate contract on these seeds). We therefore do NOT assert
1176 // utf8.ValidString(out); that would assert a contract the parser does
1177 // not claim to uphold. The differential check below is the honest gate:
1178 // for any token encoding/json accepts, ParseString MUST produce the same
1179 // output. Disagreement there is a genuine unescape bug.
1180 //
1181 // Cross-check against encoding/json's reference unescaper. Wrap val back
1182 // into a JSON string literal so json.Unmarshal sees the same token.
1183 // Restricted to valid-UTF-8 inputs because the two implementations
1184 // DOCUMENTEDLY disagree on invalid-UTF-8 handling (jsonparser passes
1185 // raw bytes through; encoding/json substitutes U+FFFD) — that is a
1186 // design choice, not an unescape bug.
1187 quoted := make([]byte, 0, len(val)+2)
1188 quoted = append(quoted, '"')
1189 quoted = append(quoted, val...)
1190 quoted = append(quoted, '"')
1191 var ref string
1192 if jerr := json.Unmarshal(quoted, &ref); jerr == nil && utf8.Valid(val) {
1193 // Both succeeded — they must agree byte-for-byte.
1194 if out != ref {
1195 t.Errorf("ParseString disagrees with encoding/json "+
1196 "(PARSESTRING differential): ParseString(%q)=%q json.Unmarshal=%q data=%q path=%v",
1197 val, out, ref, data, path)
1198 }
1199 }
1200 // Sanity: result is bounded (catches runaway allocation in Unescape).
1201 if len(out) > len(val)*4+16 {
1202 t.Errorf("ParseString returned suspiciously large output (PARSESTRING sanity): "+
1203 "in=%d out=%d data=%q path=%v", len(val), len(out), data, path)
1204 }
1205}
1206
1207// checkParseBooleanGate (Gate 9: PARSEBOOLEAN) cross-checks ParseBoolean
1208// against strconv.ParseBool on Boolean-typed values. Closes the API-coverage

Callers 1

runStructureAwareGatesFunction · 0.85

Calls 2

GetFunction · 0.85
ParseStringFunction · 0.85

Tested by

no test coverage detected