@@ -412,11 +412,41 @@ fn (mut decoder Decoder) decode_value[T](mut val T) ! {
412412 string_buffer << `\t `
413413 }
414414 `u` {
415- string_buffer << rune (strconv.parse_uint (decoder.json[
415+ unicode_point := rune (strconv.parse_uint (decoder.json[
416416 string_info.position + string_index..string_info.position +
417- string_index + 4 ], 16 , 32 )! ). bytes ()
417+ string_index + 4 ], 16 , 32 )! )
418418
419419 string_index + = 4
420+
421+ if unicode_point < 0xD800 { // normal utf-8
422+ string_buffer << unicode_point.bytes ()
423+ } else if unicode_point > = 0xDC00 { // trail surrogate -> invalid
424+ decoder.decode_error ('Got trail surrogate: ${u32(unicode_point):04X} before head surrogate.' )!
425+ } else { // head surrogate -> treat as utf-16
426+ if string_index > string_info.length - 6 {
427+ decoder.decode_error ('Expected a trail surrogate after a head surrogate, but got no valid escape sequence.' )!
428+ }
429+ if decoder.json[string_info.position + string_index..
430+ string_info.position + string_index + 2 ] != '\\ u' {
431+ decoder.decode_error ('Expected a trail surrogate after a head surrogate, but got no valid escape sequence.' )!
432+ }
433+
434+ string_index + = 2
435+
436+ unicode_point2 := rune (strconv.parse_uint (decoder.json[
437+ string_info.position + string_index..string_info.position +
438+ string_index + 4 ], 16 , 32 )! )
439+
440+ string_index + = 4
441+
442+ if unicode_point2 < 0xDC00 {
443+ decoder.decode_error ('Expected a trail surrogate after a head surrogate, but got ${u32(unicode_point):04X} .' )!
444+ }
445+
446+ final_unicode_point := (unicode_point2 & 0x3FF ) +
447+ ((unicode_point & 0x3FF ) << 10 ) + 0x10000
448+ string_buffer << final_unicode_point.bytes ()
449+ }
420450 }
421451 else {} // has already been checked
422452 }
0 commit comments