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

Function TestDoSPerformance

json_fuzz_test.go:1644–1683  ·  view source on GitHub ↗

TestDoSPerformance is a non-fuzz regression gate that asserts the parser completes each major operation on a 1MB input within dosOpBudget. Catches O(n²) regressions in tokenEnd/blockEnd/searchKeys that pure correctness fuzzing leaves invisible (a slow-but-correct parser is still a DoS bug). Verifie

(t *testing.T)

Source from the content-addressed store, hash-verified

1642//
1643// Verifies: SYS-REQ-035 (no pathological-input hang).
1644func TestDoSPerformance(t *testing.T) {
1645 if testing.Short() {
1646 t.Skip("skipping DoS performance gate in -short mode")
1647 }
1648 // Build a ~1MB JSON document: deeply nested then a long string at the end.
1649 // Two pathological shapes are tested:
1650 // (1) Deeply nested unclosed arrays — exercises the parser's descent
1651 // cost when no closers exist.
1652 // (2) Wide flat object with a 1MB string value — exercises the
1653 // per-byte scanning cost in stringEnd.
1654 const targetBytes = 1 << 20 // 1 MiB
1655
1656 t.Run("deep_nested", func(t *testing.T) {
1657 // 100k unclosed '[' — about 100KB; loop it to 1MB if needed.
1658 depth := 100_000
1659 for depth*2 < targetBytes {
1660 depth *= 2
1661 }
1662 data := genDeepNesting(depth, false)
1663 runDoSCase(t, "Get", data, func() { _, _, _, _ = Get(data) })
1664 runDoSCase(t, "ArrayEach", data, func() {
1665 _, _ = ArrayEach(data, func([]byte, ValueType, int, error) {})
1666 })
1667 })
1668
1669 t.Run("long_string", func(t *testing.T) {
1670 // {"a":"<repeat x 1MB>"} — exercises stringEnd on a long token.
1671 body := bytes.Repeat([]byte("x"), targetBytes-8)
1672 data := make([]byte, 0, targetBytes)
1673 data = append(data, []byte(`{"a":"`)...)
1674 data = append(data, body...)
1675 data = append(data, []byte(`"}`)...)
1676 runDoSCase(t, "Get", data, func() { _, _, _, _ = Get(data, "a") })
1677 runDoSCase(t, "GetString", data, func() { _, _ = GetString(data, "a") })
1678 runDoSCase(t, "ParseString", data, func() {
1679 val, _, _, _ := Get(data, "a")
1680 _, _ = ParseString(val)
1681 })
1682 })
1683}
1684
1685// runDoSCase runs one op under the DoS budget. A panic or a timeout exceeds
1686// the budget — either is a finding.

Callers

nothing calls this directly

Calls 6

genDeepNestingFunction · 0.85
runDoSCaseFunction · 0.85
GetFunction · 0.85
ArrayEachFunction · 0.85
GetStringFunction · 0.85
ParseStringFunction · 0.85

Tested by

no test coverage detected