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

Function genString

json_fuzz_test.go:299–377  ·  view source on GitHub ↗

genString emits a JSON string value. Includes empty "", ASCII, strings with escape sequences, unicode escapes, and long strings.

(r *rand.Rand, buf *[]byte)

Source from the content-addressed store, hash-verified

297// genString emits a JSON string value. Includes empty "", ASCII, strings
298// with escape sequences, unicode escapes, and long strings.
299func genString(r *rand.Rand, buf *[]byte) {
300 *buf = append(*buf, '"')
301 switch r.Intn(22) {
302 case 0: // empty string
303 case 1: // ASCII short
304 for i := 0; i < 1+r.Intn(8); i++ {
305 *buf = append(*buf, byte('a'+r.Intn(26)))
306 }
307 case 2: // escape sequences (all 8 JSON escapes incl. \b and \f)
308 escapes := [][]byte{[]byte(`\n`), []byte(`\t`), []byte(`\"`), []byte(`\\`), []byte(`\/`), []byte(`\r`), []byte(`\b`), []byte(`\f`)}
309 for i := 0; i < 1+r.Intn(4); i++ {
310 *buf = append(*buf, escapes[r.Intn(len(escapes))]...)
311 }
312 case 3: // unicode escape (BMP non-surrogate, hiragana range)
313 *buf = append(*buf, '\\', 'u', '3', '0')
314 *buf = append(*buf, hexDigit(r), hexDigit(r))
315 case 4: // long string (stress allocation)
316 for i := 0; i < 50+r.Intn(50); i++ {
317 *buf = append(*buf, byte('a'+r.Intn(26)))
318 }
319 case 5: // mixed content with escapes
320 *buf = append(*buf, []byte(`hello\nworld\u2603`)...)
321 case 6: // numeric-looking string (tests type coercion in callers)
322 *buf = append(*buf, '1', '2', '3', '4', '5')
323 case 7: // whitespace inside string (properly escaped — raw control
324 // bytes like 0x09 are invalid inside JSON strings per RFC 8259,
325 // so we emit the \t escape sequence instead of a literal tab).
326 *buf = append(*buf, ' ', '\\', 't')
327 // --- raw multibyte UTF-8 (parser indexes BYTES not runes) ---
328 case 8: // 2-byte UTF-8 raw (U+0080–U+07FF: accented Latin, Greek, Cyrillic)
329 var u [4]byte
330 n := utf8.EncodeRune(u[:], rune(0x80+r.Intn(0x780)))
331 *buf = append(*buf, u[:n]...)
332 case 9: // 3-byte UTF-8 raw (U+0800–U+FFFF: CJK, Arabic, Hindi)
333 var u [4]byte
334 n := utf8.EncodeRune(u[:], rune(0x800+r.Intn(0xF800)))
335 *buf = append(*buf, u[:n]...)
336 case 10: // 4-byte UTF-8 raw (U+10000+: emoji, math symbols, CJK ext.)
337 var u [4]byte
338 cp := 0x10000 + r.Intn(0x10FFFF-0x10000+1)
339 n := utf8.EncodeRune(u[:], rune(cp))
340 *buf = append(*buf, u[:n]...)
341 // --- surrogate-pair escapes (the escape decoder must combine these) ---
342 case 11: // valid surrogate pair (\uXXXX\uXXXX → U+10000..U+10FFFF)
343 cp := 0x10000 + r.Intn(0x10FFFF-0x10000+1)
344 cp -= 0x10000
345 appendUnicodeEscape(buf, 0xD800+(cp>>10))
346 appendUnicodeEscape(buf, 0xDC00+(cp&0x3FF))
347 case 12: // lone high surrogate (malformed — parser must reject)
348 appendUnicodeEscape(buf, 0xD800+r.Intn(0x400))
349 case 13: // lone low surrogate (malformed — parser must reject)
350 appendUnicodeEscape(buf, 0xDC00+r.Intn(0x400))
351 case 14: // two high surrogates back-to-back (malformed)
352 appendUnicodeEscape(buf, 0xD800+r.Intn(0x400))
353 appendUnicodeEscape(buf, 0xD800+r.Intn(0x400))
354 // --- control characters (escaped form, valid JSON) ---
355 case 15: // escaped null and unit separator
356 appendUnicodeEscape(buf, 0x00) // \u0000

Callers 1

genValueFunction · 0.85

Calls 2

hexDigitFunction · 0.85
appendUnicodeEscapeFunction · 0.85

Tested by

no test coverage detected