truncateMidKey cuts inside a string key. The cut is placed between the opening '"' of a key and its closing '"'. This is the truncated_mid_key class: the parser's Unescape routine must detect the unterminated string.
(r *rand.Rand, data []byte)
| 586 | // opening '"' of a key and its closing '"'. This is the truncated_mid_key |
| 587 | // class: the parser's Unescape routine must detect the unterminated string. |
| 588 | func truncateMidKey(r *rand.Rand, data []byte) []byte { |
| 589 | var cuts []int |
| 590 | for i := 1; i < len(data); i++ { |
| 591 | if data[i] != '"' { |
| 592 | continue |
| 593 | } |
| 594 | // Walk back past whitespace to find the structural predecessor. |
| 595 | j := i - 1 |
| 596 | for j >= 0 && (data[j] == ' ' || data[j] == '\t' || data[j] == '\n' || data[j] == '\r') { |
| 597 | j-- |
| 598 | } |
| 599 | if j < 0 || (data[j] != '{' && data[j] != ',') { |
| 600 | continue |
| 601 | } |
| 602 | // This '"' is a key opening. Find the closing '"'. |
| 603 | end := -1 |
| 604 | for k := i + 1; k < len(data); k++ { |
| 605 | if data[k] == '"' && data[k-1] != '\\' { |
| 606 | end = k |
| 607 | break |
| 608 | } |
| 609 | } |
| 610 | lo := i + 1 |
| 611 | hi := end |
| 612 | if hi < 0 || hi > len(data) { |
| 613 | hi = len(data) |
| 614 | } |
| 615 | if hi > lo { |
| 616 | cuts = append(cuts, lo+r.Intn(hi-lo)) |
| 617 | } |
| 618 | } |
| 619 | if len(cuts) == 0 { |
| 620 | return data |
| 621 | } |
| 622 | cut := cuts[r.Intn(len(cuts))] |
| 623 | out := make([]byte, cut) |
| 624 | copy(out, data[:cut]) |
| 625 | return out |
| 626 | } |
| 627 | |
| 628 | // truncateMidStructure cuts after an unclosed '{' or '['. This is the |
| 629 | // truncated_mid_structure class: the parser must detect the missing closing |
nothing calls this directly
no outgoing calls
no test coverage detected