decode_test.go 21 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. // Copyright 2019 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package json_test
  5. import (
  6. "strings"
  7. "testing"
  8. "unicode/utf8"
  9. "google.golang.org/protobuf/internal/encoding/json"
  10. )
  11. type R struct {
  12. // T is expected Type returned from calling Decoder.Read.
  13. T json.Type
  14. // E is expected error substring from calling Decoder.Read if set.
  15. E string
  16. // V is expected value from calling
  17. // Value.{Bool()|Float()|Int()|Uint()|String()} depending on type.
  18. V interface{}
  19. // VE is expected error substring from calling
  20. // Value.{Bool()|Float()|Int()|Uint()|String()} depending on type if set.
  21. VE string
  22. }
  23. func TestDecoder(t *testing.T) {
  24. const space = " \n\r\t"
  25. tests := []struct {
  26. input string
  27. // want is a list of expected values returned from calling
  28. // Decoder.Read. An item makes the test code invoke
  29. // Decoder.Read and compare against R.T and R.E. For Bool,
  30. // Number and String tokens, it invokes the corresponding getter method
  31. // and compares the returned value against R.V or R.VE if it returned an
  32. // error.
  33. want []R
  34. }{
  35. {
  36. input: ``,
  37. want: []R{{T: json.EOF}},
  38. },
  39. {
  40. input: space,
  41. want: []R{{T: json.EOF}},
  42. },
  43. {
  44. // Calling Read after EOF will keep returning EOF for
  45. // succeeding Read calls.
  46. input: space,
  47. want: []R{
  48. {T: json.EOF},
  49. {T: json.EOF},
  50. {T: json.EOF},
  51. },
  52. },
  53. // JSON literals.
  54. {
  55. input: space + `null` + space,
  56. want: []R{
  57. {T: json.Null},
  58. {T: json.EOF},
  59. },
  60. },
  61. {
  62. input: space + `true` + space,
  63. want: []R{
  64. {T: json.Bool, V: true},
  65. {T: json.EOF},
  66. },
  67. },
  68. {
  69. input: space + `false` + space,
  70. want: []R{
  71. {T: json.Bool, V: false},
  72. {T: json.EOF},
  73. },
  74. },
  75. {
  76. // Error returned will produce the same error again.
  77. input: space + `foo` + space,
  78. want: []R{
  79. {E: `invalid value foo`},
  80. {E: `invalid value foo`},
  81. },
  82. },
  83. // JSON strings.
  84. {
  85. input: space + `""` + space,
  86. want: []R{
  87. {T: json.String, V: ""},
  88. {T: json.EOF},
  89. },
  90. },
  91. {
  92. input: space + `"hello"` + space,
  93. want: []R{
  94. {T: json.String, V: "hello"},
  95. {T: json.EOF},
  96. },
  97. },
  98. {
  99. input: `"hello`,
  100. want: []R{{E: `unexpected EOF`}},
  101. },
  102. {
  103. input: "\"\x00\"",
  104. want: []R{{E: `invalid character '\x00' in string`}},
  105. },
  106. {
  107. input: "\"\u0031\u0032\"",
  108. want: []R{
  109. {T: json.String, V: "12"},
  110. {T: json.EOF},
  111. },
  112. },
  113. {
  114. // Invalid UTF-8 error is returned in ReadString instead of Read.
  115. input: "\"\xff\"",
  116. want: []R{{E: `syntax error (line 1:1): invalid UTF-8 in string`}},
  117. },
  118. {
  119. input: `"` + string(utf8.RuneError) + `"`,
  120. want: []R{
  121. {T: json.String, V: string(utf8.RuneError)},
  122. {T: json.EOF},
  123. },
  124. },
  125. {
  126. input: `"\uFFFD"`,
  127. want: []R{
  128. {T: json.String, V: string(utf8.RuneError)},
  129. {T: json.EOF},
  130. },
  131. },
  132. {
  133. input: `"\x"`,
  134. want: []R{{E: `invalid escape code "\\x" in string`}},
  135. },
  136. {
  137. input: `"\uXXXX"`,
  138. want: []R{{E: `invalid escape code "\\uXXXX" in string`}},
  139. },
  140. {
  141. input: `"\uDEAD"`, // unmatched surrogate pair
  142. want: []R{{E: `unexpected EOF`}},
  143. },
  144. {
  145. input: `"\uDEAD\uBEEF"`, // invalid surrogate half
  146. want: []R{{E: `invalid escape code "\\uBEEF" in string`}},
  147. },
  148. {
  149. input: `"\uD800\udead"`, // valid surrogate pair
  150. want: []R{
  151. {T: json.String, V: `𐊭`},
  152. {T: json.EOF},
  153. },
  154. },
  155. {
  156. input: `"\u0000\"\\\/\b\f\n\r\t"`,
  157. want: []R{
  158. {T: json.String, V: "\u0000\"\\/\b\f\n\r\t"},
  159. {T: json.EOF},
  160. },
  161. },
  162. // Invalid JSON numbers.
  163. {
  164. input: `-`,
  165. want: []R{{E: `invalid number -`}},
  166. },
  167. {
  168. input: `+0`,
  169. want: []R{{E: `invalid value +0`}},
  170. },
  171. {
  172. input: `-+`,
  173. want: []R{{E: `invalid number -+`}},
  174. },
  175. {
  176. input: `0.`,
  177. want: []R{{E: `invalid number 0.`}},
  178. },
  179. {
  180. input: `.1`,
  181. want: []R{{E: `invalid value .1`}},
  182. },
  183. {
  184. input: `1.0.1`,
  185. want: []R{{E: `invalid number 1.0.1`}},
  186. },
  187. {
  188. input: `1..1`,
  189. want: []R{{E: `invalid number 1..1`}},
  190. },
  191. {
  192. input: `-1-2`,
  193. want: []R{{E: `invalid number -1-2`}},
  194. },
  195. {
  196. input: `01`,
  197. want: []R{{E: `invalid number 01`}},
  198. },
  199. {
  200. input: `1e`,
  201. want: []R{{E: `invalid number 1e`}},
  202. },
  203. {
  204. input: `1e1.2`,
  205. want: []R{{E: `invalid number 1e1.2`}},
  206. },
  207. {
  208. input: `1Ee`,
  209. want: []R{{E: `invalid number 1Ee`}},
  210. },
  211. {
  212. input: `1.e1`,
  213. want: []R{{E: `invalid number 1.e1`}},
  214. },
  215. {
  216. input: `1.e+`,
  217. want: []R{{E: `invalid number 1.e+`}},
  218. },
  219. {
  220. input: `1e+-2`,
  221. want: []R{{E: `invalid number 1e+-2`}},
  222. },
  223. {
  224. input: `1e--2`,
  225. want: []R{{E: `invalid number 1e--2`}},
  226. },
  227. {
  228. input: `1.0true`,
  229. want: []R{{E: `invalid number 1.0true`}},
  230. },
  231. // JSON numbers as floating point.
  232. {
  233. input: space + `0.0` + space,
  234. want: []R{
  235. {T: json.Number, V: float32(0)},
  236. {T: json.EOF},
  237. },
  238. },
  239. {
  240. input: space + `0` + space,
  241. want: []R{
  242. {T: json.Number, V: float32(0)},
  243. {T: json.EOF},
  244. },
  245. },
  246. {
  247. input: space + `-0` + space,
  248. want: []R{
  249. {T: json.Number, V: float32(0)},
  250. {T: json.EOF},
  251. },
  252. },
  253. {
  254. input: `-1.02`,
  255. want: []R{
  256. {T: json.Number, V: float32(-1.02)},
  257. {T: json.EOF},
  258. },
  259. },
  260. {
  261. input: `1.020000`,
  262. want: []R{
  263. {T: json.Number, V: float32(1.02)},
  264. {T: json.EOF},
  265. },
  266. },
  267. {
  268. input: `-1.0e0`,
  269. want: []R{
  270. {T: json.Number, V: float32(-1)},
  271. {T: json.EOF},
  272. },
  273. },
  274. {
  275. input: `1.0e-000`,
  276. want: []R{
  277. {T: json.Number, V: float32(1)},
  278. {T: json.EOF},
  279. },
  280. },
  281. {
  282. input: `1e+00`,
  283. want: []R{
  284. {T: json.Number, V: float32(1)},
  285. {T: json.EOF},
  286. },
  287. },
  288. {
  289. input: `1.02e3`,
  290. want: []R{
  291. {T: json.Number, V: float32(1.02e3)},
  292. {T: json.EOF},
  293. },
  294. },
  295. {
  296. input: `-1.02E03`,
  297. want: []R{
  298. {T: json.Number, V: float32(-1.02e3)},
  299. {T: json.EOF},
  300. },
  301. },
  302. {
  303. input: `1.0200e+3`,
  304. want: []R{
  305. {T: json.Number, V: float32(1.02e3)},
  306. {T: json.EOF},
  307. },
  308. },
  309. {
  310. input: `-1.0200E+03`,
  311. want: []R{
  312. {T: json.Number, V: float32(-1.02e3)},
  313. {T: json.EOF},
  314. },
  315. },
  316. {
  317. input: `1.0200e-3`,
  318. want: []R{
  319. {T: json.Number, V: float32(1.02e-3)},
  320. {T: json.EOF},
  321. },
  322. },
  323. {
  324. input: `-1.0200E-03`,
  325. want: []R{
  326. {T: json.Number, V: float32(-1.02e-3)},
  327. {T: json.EOF},
  328. },
  329. },
  330. {
  331. // Exceeds max float32 limit, but should be ok for float64.
  332. input: `3.4e39`,
  333. want: []R{
  334. {T: json.Number, V: float64(3.4e39)},
  335. {T: json.EOF},
  336. },
  337. },
  338. {
  339. // Exceeds max float32 limit.
  340. input: `3.4e39`,
  341. want: []R{
  342. {T: json.Number, V: float32(0), VE: `value out of range`},
  343. {T: json.EOF},
  344. },
  345. },
  346. {
  347. // Less than negative max float32 limit.
  348. input: `-3.4e39`,
  349. want: []R{
  350. {T: json.Number, V: float32(0), VE: `value out of range`},
  351. {T: json.EOF},
  352. },
  353. },
  354. {
  355. // Exceeds max float64 limit.
  356. input: `1.79e+309`,
  357. want: []R{
  358. {T: json.Number, V: float64(0), VE: `value out of range`},
  359. {T: json.EOF},
  360. },
  361. },
  362. {
  363. // Less than negative max float64 limit.
  364. input: `-1.79e+309`,
  365. want: []R{
  366. {T: json.Number, V: float64(0), VE: `value out of range`},
  367. {T: json.EOF},
  368. },
  369. },
  370. // JSON numbers as signed integers.
  371. {
  372. input: space + `0` + space,
  373. want: []R{
  374. {T: json.Number, V: int32(0)},
  375. {T: json.EOF},
  376. },
  377. },
  378. {
  379. input: space + `-0` + space,
  380. want: []R{
  381. {T: json.Number, V: int32(0)},
  382. {T: json.EOF},
  383. },
  384. },
  385. {
  386. // Fractional part equals 0 is ok.
  387. input: `1.00000`,
  388. want: []R{
  389. {T: json.Number, V: int32(1)},
  390. {T: json.EOF},
  391. },
  392. },
  393. {
  394. // Fractional part not equals 0 returns error.
  395. input: `1.0000000001`,
  396. want: []R{
  397. {T: json.Number, V: int32(0), VE: `cannot convert 1.0000000001 to integer`},
  398. {T: json.EOF},
  399. },
  400. },
  401. {
  402. input: `0e0`,
  403. want: []R{
  404. {T: json.Number, V: int32(0)},
  405. {T: json.EOF},
  406. },
  407. },
  408. {
  409. input: `0.0E0`,
  410. want: []R{
  411. {T: json.Number, V: int32(0)},
  412. {T: json.EOF},
  413. },
  414. },
  415. {
  416. input: `0.0E10`,
  417. want: []R{
  418. {T: json.Number, V: int32(0)},
  419. {T: json.EOF},
  420. },
  421. },
  422. {
  423. input: `-1`,
  424. want: []R{
  425. {T: json.Number, V: int32(-1)},
  426. {T: json.EOF},
  427. },
  428. },
  429. {
  430. input: `1.0e+0`,
  431. want: []R{
  432. {T: json.Number, V: int32(1)},
  433. {T: json.EOF},
  434. },
  435. },
  436. {
  437. input: `-1E-0`,
  438. want: []R{
  439. {T: json.Number, V: int32(-1)},
  440. {T: json.EOF},
  441. },
  442. },
  443. {
  444. input: `1E1`,
  445. want: []R{
  446. {T: json.Number, V: int32(10)},
  447. {T: json.EOF},
  448. },
  449. },
  450. {
  451. input: `-100.00e-02`,
  452. want: []R{
  453. {T: json.Number, V: int32(-1)},
  454. {T: json.EOF},
  455. },
  456. },
  457. {
  458. input: `0.1200E+02`,
  459. want: []R{
  460. {T: json.Number, V: int64(12)},
  461. {T: json.EOF},
  462. },
  463. },
  464. {
  465. input: `0.012e2`,
  466. want: []R{
  467. {T: json.Number, V: int32(0), VE: `cannot convert 0.012e2 to integer`},
  468. {T: json.EOF},
  469. },
  470. },
  471. {
  472. input: `12e-2`,
  473. want: []R{
  474. {T: json.Number, V: int32(0), VE: `cannot convert 12e-2 to integer`},
  475. {T: json.EOF},
  476. },
  477. },
  478. {
  479. // Exceeds math.MaxInt32.
  480. input: `2147483648`,
  481. want: []R{
  482. {T: json.Number, V: int32(0), VE: `value out of range`},
  483. {T: json.EOF},
  484. },
  485. },
  486. {
  487. // Exceeds math.MinInt32.
  488. input: `-2147483649`,
  489. want: []R{
  490. {T: json.Number, V: int32(0), VE: `value out of range`},
  491. {T: json.EOF},
  492. },
  493. },
  494. {
  495. // Exceeds math.MaxInt32, but ok for int64.
  496. input: `2147483648`,
  497. want: []R{
  498. {T: json.Number, V: int64(2147483648)},
  499. {T: json.EOF},
  500. },
  501. },
  502. {
  503. // Exceeds math.MinInt32, but ok for int64.
  504. input: `-2147483649`,
  505. want: []R{
  506. {T: json.Number, V: int64(-2147483649)},
  507. {T: json.EOF},
  508. },
  509. },
  510. {
  511. // Exceeds math.MaxInt64.
  512. input: `9223372036854775808`,
  513. want: []R{
  514. {T: json.Number, V: int64(0), VE: `value out of range`},
  515. {T: json.EOF},
  516. },
  517. },
  518. {
  519. // Exceeds math.MinInt64.
  520. input: `-9223372036854775809`,
  521. want: []R{
  522. {T: json.Number, V: int64(0), VE: `value out of range`},
  523. {T: json.EOF},
  524. },
  525. },
  526. // JSON numbers as unsigned integers.
  527. {
  528. input: space + `0` + space,
  529. want: []R{
  530. {T: json.Number, V: uint32(0)},
  531. {T: json.EOF},
  532. },
  533. },
  534. {
  535. input: space + `-0` + space,
  536. want: []R{
  537. {T: json.Number, V: uint32(0)},
  538. {T: json.EOF},
  539. },
  540. },
  541. {
  542. input: `-1`,
  543. want: []R{
  544. {T: json.Number, V: uint32(0), VE: `invalid syntax`},
  545. {T: json.EOF},
  546. },
  547. },
  548. {
  549. // Exceeds math.MaxUint32.
  550. input: `4294967296`,
  551. want: []R{
  552. {T: json.Number, V: uint32(0), VE: `value out of range`},
  553. {T: json.EOF},
  554. },
  555. },
  556. {
  557. // Exceeds math.MaxUint64.
  558. input: `18446744073709551616`,
  559. want: []R{
  560. {T: json.Number, V: uint64(0), VE: `value out of range`},
  561. {T: json.EOF},
  562. },
  563. },
  564. // JSON sequence of values.
  565. {
  566. input: `true null`,
  567. want: []R{
  568. {T: json.Bool, V: true},
  569. {E: `unexpected value null`},
  570. },
  571. },
  572. {
  573. input: "null false",
  574. want: []R{
  575. {T: json.Null},
  576. {E: `unexpected value false`},
  577. },
  578. },
  579. {
  580. input: `true,false`,
  581. want: []R{
  582. {T: json.Bool, V: true},
  583. {E: `unexpected character ,`},
  584. },
  585. },
  586. {
  587. input: `47"hello"`,
  588. want: []R{
  589. {T: json.Number, V: int32(47)},
  590. {E: `unexpected value "hello"`},
  591. },
  592. },
  593. {
  594. input: `47 "hello"`,
  595. want: []R{
  596. {T: json.Number, V: int32(47)},
  597. {E: `unexpected value "hello"`},
  598. },
  599. },
  600. {
  601. input: `true 42`,
  602. want: []R{
  603. {T: json.Bool, V: true},
  604. {E: `unexpected value 42`},
  605. },
  606. },
  607. // JSON arrays.
  608. {
  609. input: space + `[]` + space,
  610. want: []R{
  611. {T: json.StartArray},
  612. {T: json.EndArray},
  613. {T: json.EOF},
  614. },
  615. },
  616. {
  617. input: space + `[` + space + `]` + space,
  618. want: []R{
  619. {T: json.StartArray},
  620. {T: json.EndArray},
  621. {T: json.EOF},
  622. },
  623. },
  624. {
  625. input: space + `[` + space,
  626. want: []R{
  627. {T: json.StartArray},
  628. {E: `unexpected EOF`},
  629. },
  630. },
  631. {
  632. input: space + `]` + space,
  633. want: []R{{E: `unexpected character ]`}},
  634. },
  635. {
  636. input: `[null,true,false, 1e1, "hello" ]`,
  637. want: []R{
  638. {T: json.StartArray},
  639. {T: json.Null},
  640. {T: json.Bool, V: true},
  641. {T: json.Bool, V: false},
  642. {T: json.Number, V: int32(10)},
  643. {T: json.String, V: "hello"},
  644. {T: json.EndArray},
  645. {T: json.EOF},
  646. },
  647. },
  648. {
  649. input: `[` + space + `true` + space + `,` + space + `"hello"` + space + `]`,
  650. want: []R{
  651. {T: json.StartArray},
  652. {T: json.Bool, V: true},
  653. {T: json.String, V: "hello"},
  654. {T: json.EndArray},
  655. {T: json.EOF},
  656. },
  657. },
  658. {
  659. input: `[` + space + `true` + space + `,` + space + `]`,
  660. want: []R{
  661. {T: json.StartArray},
  662. {T: json.Bool, V: true},
  663. {E: `unexpected character ]`},
  664. },
  665. },
  666. {
  667. input: `[` + space + `false` + space + `]`,
  668. want: []R{
  669. {T: json.StartArray},
  670. {T: json.Bool, V: false},
  671. {T: json.EndArray},
  672. {T: json.EOF},
  673. },
  674. },
  675. {
  676. input: `[` + space + `1` + space + `0` + space + `]`,
  677. want: []R{
  678. {T: json.StartArray},
  679. {T: json.Number, V: int64(1)},
  680. {E: `unexpected value 0`},
  681. },
  682. },
  683. {
  684. input: `[null`,
  685. want: []R{
  686. {T: json.StartArray},
  687. {T: json.Null},
  688. {E: `unexpected EOF`},
  689. },
  690. },
  691. {
  692. input: `[foo]`,
  693. want: []R{
  694. {T: json.StartArray},
  695. {E: `invalid value foo`},
  696. },
  697. },
  698. {
  699. input: `[{}, "hello", [true, false], null]`,
  700. want: []R{
  701. {T: json.StartArray},
  702. {T: json.StartObject},
  703. {T: json.EndObject},
  704. {T: json.String, V: "hello"},
  705. {T: json.StartArray},
  706. {T: json.Bool, V: true},
  707. {T: json.Bool, V: false},
  708. {T: json.EndArray},
  709. {T: json.Null},
  710. {T: json.EndArray},
  711. {T: json.EOF},
  712. },
  713. },
  714. {
  715. input: `[{ ]`,
  716. want: []R{
  717. {T: json.StartArray},
  718. {T: json.StartObject},
  719. {E: `unexpected character ]`},
  720. },
  721. },
  722. {
  723. input: `[[ ]`,
  724. want: []R{
  725. {T: json.StartArray},
  726. {T: json.StartArray},
  727. {T: json.EndArray},
  728. {E: `unexpected EOF`},
  729. },
  730. },
  731. {
  732. input: `[,]`,
  733. want: []R{
  734. {T: json.StartArray},
  735. {E: `unexpected character ,`},
  736. },
  737. },
  738. {
  739. input: `[true "hello"]`,
  740. want: []R{
  741. {T: json.StartArray},
  742. {T: json.Bool, V: true},
  743. {E: `unexpected value "hello"`},
  744. },
  745. },
  746. {
  747. input: `[] null`,
  748. want: []R{
  749. {T: json.StartArray},
  750. {T: json.EndArray},
  751. {E: `unexpected value null`},
  752. },
  753. },
  754. {
  755. input: `true []`,
  756. want: []R{
  757. {T: json.Bool, V: true},
  758. {E: `unexpected character [`},
  759. },
  760. },
  761. // JSON objects.
  762. {
  763. input: space + `{}` + space,
  764. want: []R{
  765. {T: json.StartObject},
  766. {T: json.EndObject},
  767. {T: json.EOF},
  768. },
  769. },
  770. {
  771. input: space + `{` + space + `}` + space,
  772. want: []R{
  773. {T: json.StartObject},
  774. {T: json.EndObject},
  775. {T: json.EOF},
  776. },
  777. },
  778. {
  779. input: space + `{` + space,
  780. want: []R{
  781. {T: json.StartObject},
  782. {E: `unexpected EOF`},
  783. },
  784. },
  785. {
  786. input: space + `}` + space,
  787. want: []R{{E: `unexpected character }`}},
  788. },
  789. {
  790. input: `{` + space + `null` + space + `}`,
  791. want: []R{
  792. {T: json.StartObject},
  793. {E: `unexpected value null`},
  794. },
  795. },
  796. {
  797. input: `{[]}`,
  798. want: []R{
  799. {T: json.StartObject},
  800. {E: `unexpected character [`},
  801. },
  802. },
  803. {
  804. input: `{,}`,
  805. want: []R{
  806. {T: json.StartObject},
  807. {E: `unexpected character ,`},
  808. },
  809. },
  810. {
  811. input: `{"345678"}`,
  812. want: []R{
  813. {T: json.StartObject},
  814. {E: `unexpected character }, missing ":" after object name`},
  815. },
  816. },
  817. {
  818. input: `{` + space + `"hello"` + space + `:` + space + `"world"` + space + `}`,
  819. want: []R{
  820. {T: json.StartObject},
  821. {T: json.Name, V: "hello"},
  822. {T: json.String, V: "world"},
  823. {T: json.EndObject},
  824. {T: json.EOF},
  825. },
  826. },
  827. {
  828. input: `{"hello" "world"}`,
  829. want: []R{
  830. {T: json.StartObject},
  831. {E: `unexpected character ", missing ":" after object name`},
  832. },
  833. },
  834. {
  835. input: `{"hello":`,
  836. want: []R{
  837. {T: json.StartObject},
  838. {T: json.Name, V: "hello"},
  839. {E: `unexpected EOF`},
  840. },
  841. },
  842. {
  843. input: `{"hello":"world"`,
  844. want: []R{
  845. {T: json.StartObject},
  846. {T: json.Name, V: "hello"},
  847. {T: json.String, V: "world"},
  848. {E: `unexpected EOF`},
  849. },
  850. },
  851. {
  852. input: `{"hello":"world",`,
  853. want: []R{
  854. {T: json.StartObject},
  855. {T: json.Name, V: "hello"},
  856. {T: json.String, V: "world"},
  857. {E: `unexpected EOF`},
  858. },
  859. },
  860. {
  861. input: `{"34":"89",}`,
  862. want: []R{
  863. {T: json.StartObject},
  864. {T: json.Name, V: "34"},
  865. {T: json.String, V: "89"},
  866. {E: `syntax error (line 1:12): unexpected character }`},
  867. },
  868. },
  869. {
  870. input: `{
  871. "number": 123e2,
  872. "bool" : false,
  873. "object": {"string": "world"},
  874. "null" : null,
  875. "array" : [1.01, "hello", true],
  876. "string": "hello"
  877. }`,
  878. want: []R{
  879. {T: json.StartObject},
  880. {T: json.Name, V: "number"},
  881. {T: json.Number, V: int32(12300)},
  882. {T: json.Name, V: "bool"},
  883. {T: json.Bool, V: false},
  884. {T: json.Name, V: "object"},
  885. {T: json.StartObject},
  886. {T: json.Name, V: "string"},
  887. {T: json.String, V: "world"},
  888. {T: json.EndObject},
  889. {T: json.Name, V: "null"},
  890. {T: json.Null},
  891. {T: json.Name, V: "array"},
  892. {T: json.StartArray},
  893. {T: json.Number, V: float32(1.01)},
  894. {T: json.String, V: "hello"},
  895. {T: json.Bool, V: true},
  896. {T: json.EndArray},
  897. {T: json.Name, V: "string"},
  898. {T: json.String, V: "hello"},
  899. {T: json.EndObject},
  900. {T: json.EOF},
  901. },
  902. },
  903. {
  904. input: `[
  905. {"object": {"number": 47}},
  906. ["list"],
  907. null
  908. ]`,
  909. want: []R{
  910. {T: json.StartArray},
  911. {T: json.StartObject},
  912. {T: json.Name, V: "object"},
  913. {T: json.StartObject},
  914. {T: json.Name, V: "number"},
  915. {T: json.Number, V: uint32(47)},
  916. {T: json.EndObject},
  917. {T: json.EndObject},
  918. {T: json.StartArray},
  919. {T: json.String, V: "list"},
  920. {T: json.EndArray},
  921. {T: json.Null},
  922. {T: json.EndArray},
  923. {T: json.EOF},
  924. },
  925. },
  926. // Tests for line and column info.
  927. {
  928. input: `12345678 x`,
  929. want: []R{
  930. {T: json.Number, V: int64(12345678)},
  931. {E: `syntax error (line 1:10): invalid value x`},
  932. },
  933. },
  934. {
  935. input: "\ntrue\n x",
  936. want: []R{
  937. {T: json.Bool, V: true},
  938. {E: `syntax error (line 3:4): invalid value x`},
  939. },
  940. },
  941. {
  942. input: `"💩"x`,
  943. want: []R{
  944. {T: json.String, V: "💩"},
  945. {E: `syntax error (line 1:4): invalid value x`},
  946. },
  947. },
  948. {
  949. input: "\n\n[\"🔥🔥🔥\"x",
  950. want: []R{
  951. {T: json.StartArray},
  952. {T: json.String, V: "🔥🔥🔥"},
  953. {E: `syntax error (line 3:7): invalid value x`},
  954. },
  955. },
  956. {
  957. // Multi-rune emojis.
  958. input: `["👍🏻👍🏿"x`,
  959. want: []R{
  960. {T: json.StartArray},
  961. {T: json.String, V: "👍🏻👍🏿"},
  962. {E: `syntax error (line 1:8): invalid value x`},
  963. },
  964. },
  965. {
  966. input: `{
  967. "45678":-1
  968. }`,
  969. want: []R{
  970. {T: json.StartObject},
  971. {T: json.Name, V: "45678"},
  972. {T: json.Number, V: uint64(1), VE: "error (line 2:11)"},
  973. },
  974. },
  975. }
  976. for _, tc := range tests {
  977. tc := tc
  978. t.Run("", func(t *testing.T) {
  979. dec := json.NewDecoder([]byte(tc.input))
  980. for i, want := range tc.want {
  981. typ := dec.Peek()
  982. if typ != want.T {
  983. t.Errorf("input: %v\nPeek() got %v want %v", tc.input, typ, want.T)
  984. }
  985. value, err := dec.Read()
  986. if err != nil {
  987. if want.E == "" {
  988. t.Errorf("input: %v\nRead() got unexpected error: %v", tc.input, err)
  989. } else if !strings.Contains(err.Error(), want.E) {
  990. t.Errorf("input: %v\nRead() got %q, want %q", tc.input, err, want.E)
  991. }
  992. } else {
  993. if want.E != "" {
  994. t.Errorf("input: %v\nRead() got nil error, want %q", tc.input, want.E)
  995. }
  996. }
  997. token := value.Type()
  998. if token != want.T {
  999. t.Errorf("input: %v\nRead() got %v, want %v", tc.input, token, want.T)
  1000. break
  1001. }
  1002. checkValue(t, value, i, want)
  1003. }
  1004. })
  1005. }
  1006. }
  1007. func checkValue(t *testing.T, value json.Value, wantIdx int, want R) {
  1008. var got interface{}
  1009. var err error
  1010. switch value.Type() {
  1011. case json.Bool:
  1012. got, err = value.Bool()
  1013. case json.String:
  1014. got = value.String()
  1015. case json.Name:
  1016. got, err = value.Name()
  1017. case json.Number:
  1018. switch want.V.(type) {
  1019. case float32:
  1020. got, err = value.Float(32)
  1021. got = float32(got.(float64))
  1022. case float64:
  1023. got, err = value.Float(64)
  1024. case int32:
  1025. got, err = value.Int(32)
  1026. got = int32(got.(int64))
  1027. case int64:
  1028. got, err = value.Int(64)
  1029. case uint32:
  1030. got, err = value.Uint(32)
  1031. got = uint32(got.(uint64))
  1032. case uint64:
  1033. got, err = value.Uint(64)
  1034. }
  1035. default:
  1036. return
  1037. }
  1038. if err != nil {
  1039. if want.VE == "" {
  1040. t.Errorf("want%d: %v got unexpected error: %v", wantIdx, value, err)
  1041. } else if !strings.Contains(err.Error(), want.VE) {
  1042. t.Errorf("want#%d: %v got %q, want %q", wantIdx, value, err, want.VE)
  1043. }
  1044. return
  1045. } else {
  1046. if want.VE != "" {
  1047. t.Errorf("want#%d: %v got nil error, want %q", wantIdx, value, want.VE)
  1048. return
  1049. }
  1050. }
  1051. if got != want.V {
  1052. t.Errorf("want#%d: %v got %v, want %v", wantIdx, value, got, want.V)
  1053. }
  1054. }
  1055. func TestClone(t *testing.T) {
  1056. input := `{"outer":{"str":"hello", "number": 123}}`
  1057. dec := json.NewDecoder([]byte(input))
  1058. // Clone at the start should produce the same reads as the original.
  1059. clone := dec.Clone()
  1060. compareDecoders(t, dec, clone)
  1061. // Advance to inner object, clone and compare again.
  1062. dec.Read() // Read StartObject.
  1063. dec.Read() // Read Name.
  1064. clone = dec.Clone()
  1065. compareDecoders(t, dec, clone)
  1066. }
  1067. func compareDecoders(t *testing.T, d1 *json.Decoder, d2 *json.Decoder) {
  1068. for {
  1069. v1, err1 := d1.Read()
  1070. v2, err2 := d2.Read()
  1071. if v1.Type() != v2.Type() {
  1072. t.Errorf("cloned decoder: got Type %v, want %v", v2.Type(), v1.Type())
  1073. }
  1074. if v1.Raw() != v2.Raw() {
  1075. t.Errorf("cloned decoder: got Raw %v, want %v", v2.Raw(), v1.Raw())
  1076. }
  1077. if err1 != err2 {
  1078. t.Errorf("cloned decoder: got error %v, want %v", err2, err1)
  1079. }
  1080. if v1.Type() == json.EOF {
  1081. break
  1082. }
  1083. }
  1084. }