genKey emits a JSON object key (a double-quoted string). The key content is drawn from a weighted distribution that includes the cases most likely to expose parser bugs: - empty string "" (the empty-key hazard class, SYS-REQ-111) - unicode escapes \uXXXX (escape-parsing paths) - long keys (allocatio
(r *rand.Rand, buf *[]byte)
| 237 | // - long keys (allocation paths) |
| 238 | // - escaped special chars (\\, \", \n, \t — escape correctness) |
| 239 | func genKey(r *rand.Rand, buf *[]byte) { |
| 240 | *buf = append(*buf, '"') |
| 241 | switch r.Intn(16) { |
| 242 | case 0: // empty string key |
| 243 | case 1: // single ASCII char |
| 244 | *buf = append(*buf, byte('a'+r.Intn(26))) |
| 245 | case 2: // short ASCII (1–8 chars) |
| 246 | for i := 0; i < 1+r.Intn(8); i++ { |
| 247 | *buf = append(*buf, byte('a'+r.Intn(26))) |
| 248 | } |
| 249 | case 3: // unicode escape sequence \u30XX (hiragana range) |
| 250 | *buf = append(*buf, '\\', 'u', '3', '0') |
| 251 | *buf = append(*buf, hexDigit(r), hexDigit(r)) |
| 252 | case 4: // long key (stress allocation paths) |
| 253 | for i := 0; i < 20+r.Intn(30); i++ { |
| 254 | *buf = append(*buf, byte('a'+r.Intn(26))) |
| 255 | } |
| 256 | case 5: // escaped special chars (always valid JSON) |
| 257 | *buf = append(*buf, '\\', '"', '\\', '\\', '\\', 'n', '\\', 't') |
| 258 | case 6: // numeric-looking key |
| 259 | *buf = append(*buf, '0', '0', '7') |
| 260 | case 7: // "key" (matches common test seeds) |
| 261 | *buf = append(*buf, 'k', 'e', 'y') |
| 262 | // --- raw multibyte UTF-8 keys (parser indexes BYTES not runes) --- |
| 263 | case 8: // 2-byte UTF-8 raw key (Latin/Greek/Cyrillic) |
| 264 | var u [4]byte |
| 265 | n := utf8.EncodeRune(u[:], rune(0x80+r.Intn(0x780))) |
| 266 | *buf = append(*buf, u[:n]...) |
| 267 | case 9: // 3-byte UTF-8 raw key (CJK/Arabic/Hindi) |
| 268 | var u [4]byte |
| 269 | n := utf8.EncodeRune(u[:], rune(0x800+r.Intn(0xF800))) |
| 270 | *buf = append(*buf, u[:n]...) |
| 271 | case 10: // valid surrogate-pair escape key (U+10000+) |
| 272 | cp := 0x10000 + r.Intn(0x10FFFF-0x10000+1) |
| 273 | cp -= 0x10000 |
| 274 | appendUnicodeEscape(buf, 0xD800+(cp>>10)) |
| 275 | appendUnicodeEscape(buf, 0xDC00+(cp&0x3FF)) |
| 276 | case 11: // lone surrogate escape key (malformed — parser must reject) |
| 277 | appendUnicodeEscape(buf, 0xD800+r.Intn(0x800)) |
| 278 | case 12: // escaped control char key (\u0000 / \u001F) |
| 279 | appendUnicodeEscape(buf, r.Intn(0x20)) |
| 280 | case 13: // invalid UTF-8 raw bytes in key (overlong / truncated / FF) |
| 281 | switch r.Intn(3) { |
| 282 | case 0: |
| 283 | *buf = append(*buf, 0xC0, 0xAF) |
| 284 | case 1: |
| 285 | *buf = append(*buf, 0xE0) |
| 286 | default: |
| 287 | *buf = append(*buf, 0xFF) |
| 288 | } |
| 289 | case 14: // BOM-prefixed key |
| 290 | *buf = append(*buf, 0xEF, 0xBB, 0xBF, 'k') |
| 291 | default: // 2-char ASCII |
| 292 | *buf = append(*buf, byte('a'+r.Intn(26)), byte('a'+r.Intn(26))) |
| 293 | } |
| 294 | *buf = append(*buf, '"') |
| 295 | } |
| 296 |
no test coverage detected