context.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. package decoder
  2. import (
  3. "sync"
  4. "unsafe"
  5. "github.com/goccy/go-json/internal/errors"
  6. )
  7. type RuntimeContext struct {
  8. Buf []byte
  9. Option *Option
  10. }
  11. var (
  12. runtimeContextPool = sync.Pool{
  13. New: func() interface{} {
  14. return &RuntimeContext{
  15. Option: &Option{},
  16. }
  17. },
  18. }
  19. )
  20. func TakeRuntimeContext() *RuntimeContext {
  21. return runtimeContextPool.Get().(*RuntimeContext)
  22. }
  23. func ReleaseRuntimeContext(ctx *RuntimeContext) {
  24. runtimeContextPool.Put(ctx)
  25. }
  26. var (
  27. isWhiteSpace = [256]bool{}
  28. )
  29. func init() {
  30. isWhiteSpace[' '] = true
  31. isWhiteSpace['\n'] = true
  32. isWhiteSpace['\t'] = true
  33. isWhiteSpace['\r'] = true
  34. }
  35. func char(ptr unsafe.Pointer, offset int64) byte {
  36. return *(*byte)(unsafe.Pointer(uintptr(ptr) + uintptr(offset)))
  37. }
  38. func skipWhiteSpace(buf []byte, cursor int64) int64 {
  39. for isWhiteSpace[buf[cursor]] {
  40. cursor++
  41. }
  42. return cursor
  43. }
  44. func skipObject(buf []byte, cursor, depth int64) (int64, error) {
  45. braceCount := 1
  46. for {
  47. switch buf[cursor] {
  48. case '{':
  49. braceCount++
  50. depth++
  51. if depth > maxDecodeNestingDepth {
  52. return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
  53. }
  54. case '}':
  55. depth--
  56. braceCount--
  57. if braceCount == 0 {
  58. return cursor + 1, nil
  59. }
  60. case '[':
  61. depth++
  62. if depth > maxDecodeNestingDepth {
  63. return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
  64. }
  65. case ']':
  66. depth--
  67. case '"':
  68. for {
  69. cursor++
  70. switch buf[cursor] {
  71. case '\\':
  72. cursor++
  73. if buf[cursor] == nul {
  74. return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
  75. }
  76. case '"':
  77. goto SWITCH_OUT
  78. case nul:
  79. return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
  80. }
  81. }
  82. case nul:
  83. return 0, errors.ErrUnexpectedEndOfJSON("object of object", cursor)
  84. }
  85. SWITCH_OUT:
  86. cursor++
  87. }
  88. }
  89. func skipArray(buf []byte, cursor, depth int64) (int64, error) {
  90. bracketCount := 1
  91. for {
  92. switch buf[cursor] {
  93. case '[':
  94. bracketCount++
  95. depth++
  96. if depth > maxDecodeNestingDepth {
  97. return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
  98. }
  99. case ']':
  100. bracketCount--
  101. depth--
  102. if bracketCount == 0 {
  103. return cursor + 1, nil
  104. }
  105. case '{':
  106. depth++
  107. if depth > maxDecodeNestingDepth {
  108. return 0, errors.ErrExceededMaxDepth(buf[cursor], cursor)
  109. }
  110. case '}':
  111. depth--
  112. case '"':
  113. for {
  114. cursor++
  115. switch buf[cursor] {
  116. case '\\':
  117. cursor++
  118. if buf[cursor] == nul {
  119. return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
  120. }
  121. case '"':
  122. goto SWITCH_OUT
  123. case nul:
  124. return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
  125. }
  126. }
  127. case nul:
  128. return 0, errors.ErrUnexpectedEndOfJSON("array of object", cursor)
  129. }
  130. SWITCH_OUT:
  131. cursor++
  132. }
  133. }
  134. func skipValue(buf []byte, cursor, depth int64) (int64, error) {
  135. for {
  136. switch buf[cursor] {
  137. case ' ', '\t', '\n', '\r':
  138. cursor++
  139. continue
  140. case '{':
  141. return skipObject(buf, cursor+1, depth+1)
  142. case '[':
  143. return skipArray(buf, cursor+1, depth+1)
  144. case '"':
  145. for {
  146. cursor++
  147. switch buf[cursor] {
  148. case '\\':
  149. cursor++
  150. if buf[cursor] == nul {
  151. return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
  152. }
  153. case '"':
  154. return cursor + 1, nil
  155. case nul:
  156. return 0, errors.ErrUnexpectedEndOfJSON("string of object", cursor)
  157. }
  158. }
  159. case '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
  160. for {
  161. cursor++
  162. if floatTable[buf[cursor]] {
  163. continue
  164. }
  165. break
  166. }
  167. return cursor, nil
  168. case 't':
  169. if err := validateTrue(buf, cursor); err != nil {
  170. return 0, err
  171. }
  172. cursor += 4
  173. return cursor, nil
  174. case 'f':
  175. if err := validateFalse(buf, cursor); err != nil {
  176. return 0, err
  177. }
  178. cursor += 5
  179. return cursor, nil
  180. case 'n':
  181. if err := validateNull(buf, cursor); err != nil {
  182. return 0, err
  183. }
  184. cursor += 4
  185. return cursor, nil
  186. default:
  187. return cursor, errors.ErrUnexpectedEndOfJSON("null", cursor)
  188. }
  189. }
  190. }
  191. func validateTrue(buf []byte, cursor int64) error {
  192. if cursor+3 >= int64(len(buf)) {
  193. return errors.ErrUnexpectedEndOfJSON("true", cursor)
  194. }
  195. if buf[cursor+1] != 'r' {
  196. return errors.ErrInvalidCharacter(buf[cursor+1], "true", cursor)
  197. }
  198. if buf[cursor+2] != 'u' {
  199. return errors.ErrInvalidCharacter(buf[cursor+2], "true", cursor)
  200. }
  201. if buf[cursor+3] != 'e' {
  202. return errors.ErrInvalidCharacter(buf[cursor+3], "true", cursor)
  203. }
  204. return nil
  205. }
  206. func validateFalse(buf []byte, cursor int64) error {
  207. if cursor+4 >= int64(len(buf)) {
  208. return errors.ErrUnexpectedEndOfJSON("false", cursor)
  209. }
  210. if buf[cursor+1] != 'a' {
  211. return errors.ErrInvalidCharacter(buf[cursor+1], "false", cursor)
  212. }
  213. if buf[cursor+2] != 'l' {
  214. return errors.ErrInvalidCharacter(buf[cursor+2], "false", cursor)
  215. }
  216. if buf[cursor+3] != 's' {
  217. return errors.ErrInvalidCharacter(buf[cursor+3], "false", cursor)
  218. }
  219. if buf[cursor+4] != 'e' {
  220. return errors.ErrInvalidCharacter(buf[cursor+4], "false", cursor)
  221. }
  222. return nil
  223. }
  224. func validateNull(buf []byte, cursor int64) error {
  225. if cursor+3 >= int64(len(buf)) {
  226. return errors.ErrUnexpectedEndOfJSON("null", cursor)
  227. }
  228. if buf[cursor+1] != 'u' {
  229. return errors.ErrInvalidCharacter(buf[cursor+1], "null", cursor)
  230. }
  231. if buf[cursor+2] != 'l' {
  232. return errors.ErrInvalidCharacter(buf[cursor+2], "null", cursor)
  233. }
  234. if buf[cursor+3] != 'l' {
  235. return errors.ErrInvalidCharacter(buf[cursor+3], "null", cursor)
  236. }
  237. return nil
  238. }