fix #2550 json encoding should use surrogate pairs per RFC7159

This commit is contained in:
Laytan Laats
2023-05-22 17:22:33 +02:00
parent 118ab60588
commit 5d54b710e7
5 changed files with 54 additions and 13 deletions

View File

@@ -153,7 +153,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
case complex128: r, i = f64(real(z)), f64(imag(z))
case: return .Unsupported_Type
}
io.write_byte(w, '[') or_return
io.write_f64(w, r) or_return
io.write_string(w, ", ") or_return
@@ -165,8 +165,8 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
case runtime.Type_Info_String:
switch s in a {
case string: io.write_quoted_string(w, s) or_return
case cstring: io.write_quoted_string(w, string(s)) or_return
case string: io.write_quoted_string(w, s, '"', nil, true) or_return
case cstring: io.write_quoted_string(w, string(s), '"', nil, true) or_return
}
case runtime.Type_Info_Boolean:

View File

@@ -2,6 +2,7 @@ package json
import "core:mem"
import "core:unicode/utf8"
import "core:unicode/utf16"
import "core:strconv"
Parser :: struct {
@@ -403,11 +404,19 @@ unquote_string :: proc(token: Token, spec: Specification, allocator := context.a
}
i += 6
// If this is a surrogate pair, decode as such by taking the next rune too.
if r >= utf8.SURROGATE_MIN && r <= utf8.SURROGATE_HIGH_MAX && len(s) > i + 2 && s[i:i+2] == "\\u" {
r2 := get_u4_rune(s[i:])
if r2 >= utf8.SURROGATE_LOW_MIN && r2 <= utf8.SURROGATE_MAX {
i += 6
r = utf16.decode_surrogate_pair(r, r2)
}
}
buf, buf_width := utf8.encode_rune(r)
copy(b[w:], buf[:buf_width])
w += buf_width
case '0':
if spec != .JSON {
b[w] = '\x00'