string.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. package decoder
  2. import (
  3. "bytes"
  4. "fmt"
  5. "reflect"
  6. "unicode"
  7. "unicode/utf16"
  8. "unicode/utf8"
  9. "unsafe"
  10. "github.com/goccy/go-json/internal/errors"
  11. )
  12. type stringDecoder struct {
  13. structName string
  14. fieldName string
  15. }
  16. func newStringDecoder(structName, fieldName string) *stringDecoder {
  17. return &stringDecoder{
  18. structName: structName,
  19. fieldName: fieldName,
  20. }
  21. }
  22. func (d *stringDecoder) errUnmarshalType(typeName string, offset int64) *errors.UnmarshalTypeError {
  23. return &errors.UnmarshalTypeError{
  24. Value: typeName,
  25. Type: reflect.TypeOf(""),
  26. Offset: offset,
  27. Struct: d.structName,
  28. Field: d.fieldName,
  29. }
  30. }
  31. func (d *stringDecoder) DecodeStream(s *Stream, depth int64, p unsafe.Pointer) error {
  32. bytes, err := d.decodeStreamByte(s)
  33. if err != nil {
  34. return err
  35. }
  36. if bytes == nil {
  37. return nil
  38. }
  39. **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes))
  40. s.reset()
  41. return nil
  42. }
  43. func (d *stringDecoder) Decode(ctx *RuntimeContext, cursor, depth int64, p unsafe.Pointer) (int64, error) {
  44. bytes, c, err := d.decodeByte(ctx.Buf, cursor)
  45. if err != nil {
  46. return 0, err
  47. }
  48. if bytes == nil {
  49. return c, nil
  50. }
  51. cursor = c
  52. **(**string)(unsafe.Pointer(&p)) = *(*string)(unsafe.Pointer(&bytes))
  53. return cursor, nil
  54. }
  55. var (
  56. hexToInt = [256]int{
  57. '0': 0,
  58. '1': 1,
  59. '2': 2,
  60. '3': 3,
  61. '4': 4,
  62. '5': 5,
  63. '6': 6,
  64. '7': 7,
  65. '8': 8,
  66. '9': 9,
  67. 'A': 10,
  68. 'B': 11,
  69. 'C': 12,
  70. 'D': 13,
  71. 'E': 14,
  72. 'F': 15,
  73. 'a': 10,
  74. 'b': 11,
  75. 'c': 12,
  76. 'd': 13,
  77. 'e': 14,
  78. 'f': 15,
  79. }
  80. )
  81. func unicodeToRune(code []byte) rune {
  82. var r rune
  83. for i := 0; i < len(code); i++ {
  84. r = r*16 + rune(hexToInt[code[i]])
  85. }
  86. return r
  87. }
  88. func decodeUnicodeRune(s *Stream, p unsafe.Pointer) (rune, int64, unsafe.Pointer, error) {
  89. const defaultOffset = 5
  90. const surrogateOffset = 11
  91. if s.cursor+defaultOffset >= s.length {
  92. if !s.read() {
  93. return rune(0), 0, nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset())
  94. }
  95. p = s.bufptr()
  96. }
  97. r := unicodeToRune(s.buf[s.cursor+1 : s.cursor+defaultOffset])
  98. if utf16.IsSurrogate(r) {
  99. if s.cursor+surrogateOffset >= s.length {
  100. s.read()
  101. p = s.bufptr()
  102. }
  103. if s.cursor+surrogateOffset >= s.length || s.buf[s.cursor+defaultOffset] != '\\' || s.buf[s.cursor+defaultOffset+1] != 'u' {
  104. return unicode.ReplacementChar, defaultOffset, p, nil
  105. }
  106. r2 := unicodeToRune(s.buf[s.cursor+defaultOffset+2 : s.cursor+surrogateOffset])
  107. if r := utf16.DecodeRune(r, r2); r != unicode.ReplacementChar {
  108. return r, surrogateOffset, p, nil
  109. }
  110. }
  111. return r, defaultOffset, p, nil
  112. }
  113. func decodeUnicode(s *Stream, p unsafe.Pointer) (unsafe.Pointer, error) {
  114. const backSlashAndULen = 2 // length of \u
  115. r, offset, pp, err := decodeUnicodeRune(s, p)
  116. if err != nil {
  117. return nil, err
  118. }
  119. unicode := []byte(string(r))
  120. unicodeLen := int64(len(unicode))
  121. s.buf = append(append(s.buf[:s.cursor-1], unicode...), s.buf[s.cursor+offset:]...)
  122. unicodeOrgLen := offset - 1
  123. s.length = s.length - (backSlashAndULen + (unicodeOrgLen - unicodeLen))
  124. s.cursor = s.cursor - backSlashAndULen + unicodeLen
  125. return pp, nil
  126. }
  127. func decodeEscapeString(s *Stream, p unsafe.Pointer) (unsafe.Pointer, error) {
  128. s.cursor++
  129. RETRY:
  130. switch s.buf[s.cursor] {
  131. case '"':
  132. s.buf[s.cursor] = '"'
  133. case '\\':
  134. s.buf[s.cursor] = '\\'
  135. case '/':
  136. s.buf[s.cursor] = '/'
  137. case 'b':
  138. s.buf[s.cursor] = '\b'
  139. case 'f':
  140. s.buf[s.cursor] = '\f'
  141. case 'n':
  142. s.buf[s.cursor] = '\n'
  143. case 'r':
  144. s.buf[s.cursor] = '\r'
  145. case 't':
  146. s.buf[s.cursor] = '\t'
  147. case 'u':
  148. return decodeUnicode(s, p)
  149. case nul:
  150. if !s.read() {
  151. return nil, errors.ErrInvalidCharacter(s.char(), "escaped string", s.totalOffset())
  152. }
  153. goto RETRY
  154. default:
  155. return nil, errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
  156. }
  157. s.buf = append(s.buf[:s.cursor-1], s.buf[s.cursor:]...)
  158. s.length--
  159. s.cursor--
  160. p = s.bufptr()
  161. return p, nil
  162. }
  163. var (
  164. runeErrBytes = []byte(string(utf8.RuneError))
  165. runeErrBytesLen = int64(len(runeErrBytes))
  166. )
  167. func stringBytes(s *Stream) ([]byte, error) {
  168. _, cursor, p := s.stat()
  169. cursor++ // skip double quote char
  170. start := cursor
  171. for {
  172. switch char(p, cursor) {
  173. case '\\':
  174. s.cursor = cursor
  175. pp, err := decodeEscapeString(s, p)
  176. if err != nil {
  177. return nil, err
  178. }
  179. p = pp
  180. cursor = s.cursor
  181. case '"':
  182. literal := s.buf[start:cursor]
  183. cursor++
  184. s.cursor = cursor
  185. return literal, nil
  186. case
  187. // 0x00 is nul, 0x5c is '\\', 0x22 is '"' .
  188. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, // 0x00-0x0F
  189. 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, // 0x10-0x1F
  190. 0x20, 0x21 /*0x22,*/, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, // 0x20-0x2F
  191. 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, // 0x30-0x3F
  192. 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, // 0x40-0x4F
  193. 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B /*0x5C,*/, 0x5D, 0x5E, 0x5F, // 0x50-0x5F
  194. 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, // 0x60-0x6F
  195. 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F: // 0x70-0x7F
  196. // character is ASCII. skip to next char
  197. case
  198. 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, // 0x80-0x8F
  199. 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, // 0x90-0x9F
  200. 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, // 0xA0-0xAF
  201. 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, // 0xB0-0xBF
  202. 0xC0, 0xC1, // 0xC0-0xC1
  203. 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF: // 0xF5-0xFE
  204. // character is invalid
  205. s.buf = append(append(append([]byte{}, s.buf[:cursor]...), runeErrBytes...), s.buf[cursor+1:]...)
  206. _, _, p = s.stat()
  207. cursor += runeErrBytesLen
  208. s.length += runeErrBytesLen
  209. continue
  210. case nul:
  211. s.cursor = cursor
  212. if s.read() {
  213. _, cursor, p = s.stat()
  214. continue
  215. }
  216. goto ERROR
  217. case 0xEF:
  218. // RuneError is {0xEF, 0xBF, 0xBD}
  219. if s.buf[cursor+1] == 0xBF && s.buf[cursor+2] == 0xBD {
  220. // found RuneError: skip
  221. cursor += 2
  222. break
  223. }
  224. fallthrough
  225. default:
  226. // multi bytes character
  227. if !utf8.FullRune(s.buf[cursor : len(s.buf)-1]) {
  228. s.cursor = cursor
  229. if s.read() {
  230. _, cursor, p = s.stat()
  231. continue
  232. }
  233. goto ERROR
  234. }
  235. r, size := utf8.DecodeRune(s.buf[cursor:])
  236. if r == utf8.RuneError {
  237. s.buf = append(append(append([]byte{}, s.buf[:cursor]...), runeErrBytes...), s.buf[cursor+1:]...)
  238. cursor += runeErrBytesLen
  239. s.length += runeErrBytesLen
  240. _, _, p = s.stat()
  241. } else {
  242. cursor += int64(size)
  243. }
  244. continue
  245. }
  246. cursor++
  247. }
  248. ERROR:
  249. return nil, errors.ErrUnexpectedEndOfJSON("string", s.totalOffset())
  250. }
  251. func (d *stringDecoder) decodeStreamByte(s *Stream) ([]byte, error) {
  252. for {
  253. switch s.char() {
  254. case ' ', '\n', '\t', '\r':
  255. s.cursor++
  256. continue
  257. case '[':
  258. return nil, d.errUnmarshalType("array", s.totalOffset())
  259. case '{':
  260. return nil, d.errUnmarshalType("object", s.totalOffset())
  261. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  262. return nil, d.errUnmarshalType("number", s.totalOffset())
  263. case '"':
  264. return stringBytes(s)
  265. case 'n':
  266. if err := nullBytes(s); err != nil {
  267. return nil, err
  268. }
  269. return nil, nil
  270. case nul:
  271. if s.read() {
  272. continue
  273. }
  274. }
  275. break
  276. }
  277. return nil, errors.ErrInvalidBeginningOfValue(s.char(), s.totalOffset())
  278. }
  279. func (d *stringDecoder) decodeByte(buf []byte, cursor int64) ([]byte, int64, error) {
  280. for {
  281. switch buf[cursor] {
  282. case ' ', '\n', '\t', '\r':
  283. cursor++
  284. case '[':
  285. return nil, 0, d.errUnmarshalType("array", cursor)
  286. case '{':
  287. return nil, 0, d.errUnmarshalType("object", cursor)
  288. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  289. return nil, 0, d.errUnmarshalType("number", cursor)
  290. case '"':
  291. cursor++
  292. start := cursor
  293. b := (*sliceHeader)(unsafe.Pointer(&buf)).data
  294. escaped := 0
  295. for {
  296. switch char(b, cursor) {
  297. case '\\':
  298. escaped++
  299. cursor++
  300. switch char(b, cursor) {
  301. case '"', '\\', '/', 'b', 'f', 'n', 'r', 't':
  302. cursor++
  303. case 'u':
  304. buflen := int64(len(buf))
  305. if cursor+5 >= buflen {
  306. return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
  307. }
  308. for i := int64(1); i <= 4; i++ {
  309. c := char(b, cursor+i)
  310. if !(('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')) {
  311. return nil, 0, errors.ErrSyntax(fmt.Sprintf("json: invalid character %c in \\u hexadecimal character escape", c), cursor+i)
  312. }
  313. }
  314. cursor += 5
  315. default:
  316. return nil, 0, errors.ErrUnexpectedEndOfJSON("escaped string", cursor)
  317. }
  318. continue
  319. case '"':
  320. literal := buf[start:cursor]
  321. if escaped > 0 {
  322. literal = literal[:unescapeString(literal)]
  323. }
  324. cursor++
  325. return literal, cursor, nil
  326. case nul:
  327. return nil, 0, errors.ErrUnexpectedEndOfJSON("string", cursor)
  328. }
  329. cursor++
  330. }
  331. case 'n':
  332. if err := validateNull(buf, cursor); err != nil {
  333. return nil, 0, err
  334. }
  335. cursor += 4
  336. return nil, cursor, nil
  337. default:
  338. return nil, 0, errors.ErrInvalidBeginningOfValue(buf[cursor], cursor)
  339. }
  340. }
  341. }
  342. var unescapeMap = [256]byte{
  343. '"': '"',
  344. '\\': '\\',
  345. '/': '/',
  346. 'b': '\b',
  347. 'f': '\f',
  348. 'n': '\n',
  349. 'r': '\r',
  350. 't': '\t',
  351. }
  352. func unsafeAdd(ptr unsafe.Pointer, offset int) unsafe.Pointer {
  353. return unsafe.Pointer(uintptr(ptr) + uintptr(offset))
  354. }
  355. func unescapeString(buf []byte) int {
  356. p := (*sliceHeader)(unsafe.Pointer(&buf)).data
  357. end := unsafeAdd(p, len(buf))
  358. src := unsafeAdd(p, bytes.IndexByte(buf, '\\'))
  359. dst := src
  360. for src != end {
  361. c := char(src, 0)
  362. if c == '\\' {
  363. escapeChar := char(src, 1)
  364. if escapeChar != 'u' {
  365. *(*byte)(dst) = unescapeMap[escapeChar]
  366. src = unsafeAdd(src, 2)
  367. dst = unsafeAdd(dst, 1)
  368. } else {
  369. v1 := hexToInt[char(src, 2)]
  370. v2 := hexToInt[char(src, 3)]
  371. v3 := hexToInt[char(src, 4)]
  372. v4 := hexToInt[char(src, 5)]
  373. code := rune((v1 << 12) | (v2 << 8) | (v3 << 4) | v4)
  374. if code >= 0xd800 && code < 0xdc00 && uintptr(unsafeAdd(src, 11)) < uintptr(end) {
  375. if char(src, 6) == '\\' && char(src, 7) == 'u' {
  376. v1 := hexToInt[char(src, 8)]
  377. v2 := hexToInt[char(src, 9)]
  378. v3 := hexToInt[char(src, 10)]
  379. v4 := hexToInt[char(src, 11)]
  380. lo := rune((v1 << 12) | (v2 << 8) | (v3 << 4) | v4)
  381. if lo >= 0xdc00 && lo < 0xe000 {
  382. code = (code-0xd800)<<10 | (lo - 0xdc00) + 0x10000
  383. src = unsafeAdd(src, 6)
  384. }
  385. }
  386. }
  387. var b [utf8.UTFMax]byte
  388. n := utf8.EncodeRune(b[:], code)
  389. switch n {
  390. case 4:
  391. *(*byte)(unsafeAdd(dst, 3)) = b[3]
  392. fallthrough
  393. case 3:
  394. *(*byte)(unsafeAdd(dst, 2)) = b[2]
  395. fallthrough
  396. case 2:
  397. *(*byte)(unsafeAdd(dst, 1)) = b[1]
  398. fallthrough
  399. case 1:
  400. *(*byte)(unsafeAdd(dst, 0)) = b[0]
  401. }
  402. src = unsafeAdd(src, 6)
  403. dst = unsafeAdd(dst, n)
  404. }
  405. } else {
  406. *(*byte)(dst) = c
  407. src = unsafeAdd(src, 1)
  408. dst = unsafeAdd(dst, 1)
  409. }
  410. }
  411. return int(uintptr(dst) - uintptr(p))
  412. }