runTransformDoSGate runs Compact/Indent/HTMLEscape on a deeply-nested input under a wall-clock budget. A panic OR a hang is a finding.
(t *testing.T, depth int)
| 448 | // runTransformDoSGate runs Compact/Indent/HTMLEscape on a deeply-nested |
| 449 | // input under a wall-clock budget. A panic OR a hang is a finding. |
| 450 | func runTransformDoSGate(t *testing.T, depth int) { |
| 451 | t.Helper() |
| 452 | for _, shape := range []string{"open", "closed"} { |
| 453 | shape := shape |
| 454 | t.Run(fmt.Sprintf("depth_%d_%s", depth, shape), func(t *testing.T) { |
| 455 | closed := shape == "closed" |
| 456 | data := genDeepNesting(depth, closed) |
| 457 | for _, op := range []string{"Compact", "Indent", "HTMLEscape"} { |
| 458 | op := op |
| 459 | t.Run(op, func(t *testing.T) { |
| 460 | done := make(chan struct{}) |
| 461 | start := time.Now() |
| 462 | go func() { |
| 463 | defer func() { |
| 464 | if r := recover(); r != nil { |
| 465 | t.Errorf("PANIC in %s on %d-level nesting (DoS gate): %v\n%s", |
| 466 | op, depth, r, debug.Stack()) |
| 467 | } |
| 468 | close(done) |
| 469 | }() |
| 470 | var dst bytes.Buffer |
| 471 | switch op { |
| 472 | case "Compact": |
| 473 | _ = json.Compact(&dst, data) |
| 474 | case "Indent": |
| 475 | _ = json.Indent(&dst, data, "", " ") |
| 476 | case "HTMLEscape": |
| 477 | json.HTMLEscape(&dst, data) |
| 478 | } |
| 479 | }() |
| 480 | select { |
| 481 | case <-done: |
| 482 | elapsed := time.Since(start) |
| 483 | if elapsed > encodingJSONTransformBudget { |
| 484 | t.Errorf("%s took %v on %d-level nesting (budget %v exceeded)", |
| 485 | op, elapsed, depth, encodingJSONTransformBudget) |
| 486 | } |
| 487 | case <-time.After(encodingJSONTransformBudget): |
| 488 | t.Fatalf("%s hung > %v on %d-level nesting (DoS regression)", |
| 489 | op, encodingJSONTransformBudget, depth) |
| 490 | } |
| 491 | }) |
| 492 | } |
| 493 | }) |
| 494 | } |
| 495 | } |
| 496 | |
| 497 | // ============================================================================= |
| 498 | // Gate I: Marshal determinism on round-tripped values |
no test coverage detected