genNumber emits a JSON number. The distribution is weighted toward the fast-path (small ints) but includes overflow boundaries, floats, and intentionally-malformed values (leading zeros) that exercise the parser's error paths.
(r *rand.Rand, buf *[]byte)
| 399 | // intentionally-malformed values (leading zeros) that exercise the parser's |
| 400 | // error paths. |
| 401 | func genNumber(r *rand.Rand, buf *[]byte) { |
| 402 | switch r.Intn(20) { |
| 403 | case 0: // 0 |
| 404 | *buf = append(*buf, '0') |
| 405 | case 1: // small positive int (1–2 digits — the fast path) |
| 406 | *buf = strconv.AppendInt(*buf, int64(1+r.Intn(99)), 10) |
| 407 | case 2: // negative small int |
| 408 | *buf = strconv.AppendInt(*buf, -int64(1+r.Intn(99)), 10) |
| 409 | case 3: // near int64 max (overflow boundary) |
| 410 | *buf = append(*buf, nearMaxInt64[r.Intn(len(nearMaxInt64))]...) |
| 411 | case 4: // near int64 min (overflow boundary) |
| 412 | *buf = append(*buf, nearMinInt64[r.Intn(len(nearMinInt64))]...) |
| 413 | case 5: // medium int |
| 414 | *buf = strconv.AppendInt(*buf, int64(100+r.Intn(100000)), 10) |
| 415 | case 6: // float (fixed notation) |
| 416 | *buf = strconv.AppendFloat(*buf, r.Float64()*1000, 'f', 2, 64) |
| 417 | case 7: // float with exponent |
| 418 | *buf = strconv.AppendFloat(*buf, r.Float64()*1e10, 'e', -1, 64) |
| 419 | case 8: // negative float |
| 420 | *buf = strconv.AppendFloat(*buf, -r.Float64()*1000, 'f', 2, 64) |
| 421 | case 9: // leading zeros (invalid JSON per RFC 8259 but tests parser leniency) |
| 422 | *buf = append(*buf, '0', '0', '7') |
| 423 | case 10: // very small float |
| 424 | *buf = append(*buf, []byte("0.000001")...) |
| 425 | // --- exponent extremes (overflow / underflow paths) --- |
| 426 | case 11: // float overflow → +Inf |
| 427 | switch r.Intn(3) { |
| 428 | case 0: |
| 429 | *buf = append(*buf, []byte("1e999")...) |
| 430 | case 1: |
| 431 | *buf = append(*buf, []byte("1e400")...) |
| 432 | default: |
| 433 | *buf = append(*buf, []byte("2.5e500")...) |
| 434 | } |
| 435 | case 12: // float underflow → 0 |
| 436 | switch r.Intn(3) { |
| 437 | case 0: |
| 438 | *buf = append(*buf, []byte("1e-999")...) |
| 439 | case 1: |
| 440 | *buf = append(*buf, []byte("1e-400")...) |
| 441 | default: |
| 442 | *buf = append(*buf, []byte("1e-323")...) // near float64 min denormal |
| 443 | } |
| 444 | case 13: // near float64 max (1.7976931348623157e+308) |
| 445 | *buf = append(*buf, []byte("1.7976931348623157e+308")...) |
| 446 | case 14: // near float64 min denormal (5e-324) |
| 447 | *buf = append(*buf, []byte("5e-324")...) |
| 448 | // --- negative zero variants --- |
| 449 | case 15: |
| 450 | switch r.Intn(3) { |
| 451 | case 0: |
| 452 | *buf = append(*buf, '-', '0') |
| 453 | case 1: |
| 454 | *buf = append(*buf, []byte("-0.0")...) |
| 455 | default: |
| 456 | *buf = append(*buf, []byte("-0e0")...) |
| 457 | } |
| 458 | // --- very long numbers (overflow path) --- |