decode_test.go 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702
  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 jsonpb_test
  5. import (
  6. "math"
  7. "testing"
  8. protoV1 "github.com/golang/protobuf/proto"
  9. "github.com/golang/protobuf/v2/encoding/jsonpb"
  10. "github.com/golang/protobuf/v2/encoding/testprotos/pb2"
  11. "github.com/golang/protobuf/v2/encoding/testprotos/pb3"
  12. "github.com/golang/protobuf/v2/internal/scalar"
  13. "github.com/golang/protobuf/v2/proto"
  14. preg "github.com/golang/protobuf/v2/reflect/protoregistry"
  15. "github.com/golang/protobuf/v2/runtime/protoiface"
  16. knownpb "github.com/golang/protobuf/v2/types/known"
  17. )
  18. func init() {
  19. // TODO: remove these registerExtension calls when generated code registers
  20. // to V2 global registry.
  21. registerExtension(pb2.E_OptExtBool)
  22. registerExtension(pb2.E_OptExtString)
  23. registerExtension(pb2.E_OptExtEnum)
  24. registerExtension(pb2.E_OptExtNested)
  25. registerExtension(pb2.E_RptExtFixed32)
  26. registerExtension(pb2.E_RptExtEnum)
  27. registerExtension(pb2.E_RptExtNested)
  28. registerExtension(pb2.E_ExtensionsContainer_OptExtBool)
  29. registerExtension(pb2.E_ExtensionsContainer_OptExtString)
  30. registerExtension(pb2.E_ExtensionsContainer_OptExtEnum)
  31. registerExtension(pb2.E_ExtensionsContainer_OptExtNested)
  32. registerExtension(pb2.E_ExtensionsContainer_RptExtString)
  33. registerExtension(pb2.E_ExtensionsContainer_RptExtEnum)
  34. registerExtension(pb2.E_ExtensionsContainer_RptExtNested)
  35. registerExtension(pb2.E_MessageSetExtension)
  36. registerExtension(pb2.E_MessageSetExtension_MessageSetExtension)
  37. registerExtension(pb2.E_MessageSetExtension_NotMessageSetExtension)
  38. registerExtension(pb2.E_MessageSetExtension_ExtNested)
  39. registerExtension(pb2.E_FakeMessageSetExtension_MessageSetExtension)
  40. }
  41. func registerExtension(xd *protoiface.ExtensionDescV1) {
  42. preg.GlobalTypes.Register(xd.Type)
  43. }
  44. func TestUnmarshal(t *testing.T) {
  45. tests := []struct {
  46. desc string
  47. umo jsonpb.UnmarshalOptions
  48. inputMessage proto.Message
  49. inputText string
  50. wantMessage proto.Message
  51. // TODO: verify expected error message substring.
  52. wantErr bool
  53. }{{
  54. desc: "proto2 empty message",
  55. inputMessage: &pb2.Scalars{},
  56. inputText: "{}",
  57. wantMessage: &pb2.Scalars{},
  58. }, {
  59. desc: "unexpected value instead of EOF",
  60. inputMessage: &pb2.Scalars{},
  61. inputText: "{} {}",
  62. wantErr: true,
  63. }, {
  64. desc: "proto2 optional scalars set to zero values",
  65. inputMessage: &pb2.Scalars{},
  66. inputText: `{
  67. "optBool": false,
  68. "optInt32": 0,
  69. "optInt64": 0,
  70. "optUint32": 0,
  71. "optUint64": 0,
  72. "optSint32": 0,
  73. "optSint64": 0,
  74. "optFixed32": 0,
  75. "optFixed64": 0,
  76. "optSfixed32": 0,
  77. "optSfixed64": 0,
  78. "optFloat": 0,
  79. "optDouble": 0,
  80. "optBytes": "",
  81. "optString": ""
  82. }`,
  83. wantMessage: &pb2.Scalars{
  84. OptBool: scalar.Bool(false),
  85. OptInt32: scalar.Int32(0),
  86. OptInt64: scalar.Int64(0),
  87. OptUint32: scalar.Uint32(0),
  88. OptUint64: scalar.Uint64(0),
  89. OptSint32: scalar.Int32(0),
  90. OptSint64: scalar.Int64(0),
  91. OptFixed32: scalar.Uint32(0),
  92. OptFixed64: scalar.Uint64(0),
  93. OptSfixed32: scalar.Int32(0),
  94. OptSfixed64: scalar.Int64(0),
  95. OptFloat: scalar.Float32(0),
  96. OptDouble: scalar.Float64(0),
  97. OptBytes: []byte{},
  98. OptString: scalar.String(""),
  99. },
  100. }, {
  101. desc: "proto3 scalars set to zero values",
  102. inputMessage: &pb3.Scalars{},
  103. inputText: `{
  104. "sBool": false,
  105. "sInt32": 0,
  106. "sInt64": 0,
  107. "sUint32": 0,
  108. "sUint64": 0,
  109. "sSint32": 0,
  110. "sSint64": 0,
  111. "sFixed32": 0,
  112. "sFixed64": 0,
  113. "sSfixed32": 0,
  114. "sSfixed64": 0,
  115. "sFloat": 0,
  116. "sDouble": 0,
  117. "sBytes": "",
  118. "sString": ""
  119. }`,
  120. wantMessage: &pb3.Scalars{},
  121. }, {
  122. desc: "proto2 optional scalars set to null",
  123. inputMessage: &pb2.Scalars{},
  124. inputText: `{
  125. "optBool": null,
  126. "optInt32": null,
  127. "optInt64": null,
  128. "optUint32": null,
  129. "optUint64": null,
  130. "optSint32": null,
  131. "optSint64": null,
  132. "optFixed32": null,
  133. "optFixed64": null,
  134. "optSfixed32": null,
  135. "optSfixed64": null,
  136. "optFloat": null,
  137. "optDouble": null,
  138. "optBytes": null,
  139. "optString": null
  140. }`,
  141. wantMessage: &pb2.Scalars{},
  142. }, {
  143. desc: "proto3 scalars set to null",
  144. inputMessage: &pb3.Scalars{},
  145. inputText: `{
  146. "sBool": null,
  147. "sInt32": null,
  148. "sInt64": null,
  149. "sUint32": null,
  150. "sUint64": null,
  151. "sSint32": null,
  152. "sSint64": null,
  153. "sFixed32": null,
  154. "sFixed64": null,
  155. "sSfixed32": null,
  156. "sSfixed64": null,
  157. "sFloat": null,
  158. "sDouble": null,
  159. "sBytes": null,
  160. "sString": null
  161. }`,
  162. wantMessage: &pb3.Scalars{},
  163. }, {
  164. desc: "boolean",
  165. inputMessage: &pb3.Scalars{},
  166. inputText: `{"sBool": true}`,
  167. wantMessage: &pb3.Scalars{
  168. SBool: true,
  169. },
  170. }, {
  171. desc: "not boolean",
  172. inputMessage: &pb3.Scalars{},
  173. inputText: `{"sBool": "true"}`,
  174. wantErr: true,
  175. }, {
  176. desc: "float and double",
  177. inputMessage: &pb3.Scalars{},
  178. inputText: `{
  179. "sFloat": 1.234,
  180. "sDouble": 5.678
  181. }`,
  182. wantMessage: &pb3.Scalars{
  183. SFloat: 1.234,
  184. SDouble: 5.678,
  185. },
  186. }, {
  187. desc: "float and double in string",
  188. inputMessage: &pb3.Scalars{},
  189. inputText: `{
  190. "sFloat": "1.234",
  191. "sDouble": "5.678"
  192. }`,
  193. wantMessage: &pb3.Scalars{
  194. SFloat: 1.234,
  195. SDouble: 5.678,
  196. },
  197. }, {
  198. desc: "float and double in E notation",
  199. inputMessage: &pb3.Scalars{},
  200. inputText: `{
  201. "sFloat": 12.34E-1,
  202. "sDouble": 5.678e4
  203. }`,
  204. wantMessage: &pb3.Scalars{
  205. SFloat: 1.234,
  206. SDouble: 56780,
  207. },
  208. }, {
  209. desc: "float and double in string E notation",
  210. inputMessage: &pb3.Scalars{},
  211. inputText: `{
  212. "sFloat": "12.34E-1",
  213. "sDouble": "5.678e4"
  214. }`,
  215. wantMessage: &pb3.Scalars{
  216. SFloat: 1.234,
  217. SDouble: 56780,
  218. },
  219. }, {
  220. desc: "float exceeds limit",
  221. inputMessage: &pb3.Scalars{},
  222. inputText: `{"sFloat": 3.4e39}`,
  223. wantErr: true,
  224. }, {
  225. desc: "float in string exceeds limit",
  226. inputMessage: &pb3.Scalars{},
  227. inputText: `{"sFloat": "-3.4e39"}`,
  228. wantErr: true,
  229. }, {
  230. desc: "double exceeds limit",
  231. inputMessage: &pb3.Scalars{},
  232. inputText: `{"sFloat": -1.79e+309}`,
  233. wantErr: true,
  234. }, {
  235. desc: "double in string exceeds limit",
  236. inputMessage: &pb3.Scalars{},
  237. inputText: `{"sFloat": "1.79e+309"}`,
  238. wantErr: true,
  239. }, {
  240. desc: "infinites",
  241. inputMessage: &pb3.Scalars{},
  242. inputText: `{"sFloat": "Infinity", "sDouble": "-Infinity"}`,
  243. wantMessage: &pb3.Scalars{
  244. SFloat: float32(math.Inf(+1)),
  245. SDouble: math.Inf(-1),
  246. },
  247. }, {
  248. desc: "not float",
  249. inputMessage: &pb3.Scalars{},
  250. inputText: `{"sFloat": true}`,
  251. wantErr: true,
  252. }, {
  253. desc: "not double",
  254. inputMessage: &pb3.Scalars{},
  255. inputText: `{"sDouble": "not a number"}`,
  256. wantErr: true,
  257. }, {
  258. desc: "integers",
  259. inputMessage: &pb3.Scalars{},
  260. inputText: `{
  261. "sInt32": 1234,
  262. "sInt64": -1234,
  263. "sUint32": 1e2,
  264. "sUint64": 100E-2,
  265. "sSint32": 1.0,
  266. "sSint64": -1.0,
  267. "sFixed32": 1.234e+5,
  268. "sFixed64": 1200E-2,
  269. "sSfixed32": -1.234e05,
  270. "sSfixed64": -1200e-02
  271. }`,
  272. wantMessage: &pb3.Scalars{
  273. SInt32: 1234,
  274. SInt64: -1234,
  275. SUint32: 100,
  276. SUint64: 1,
  277. SSint32: 1,
  278. SSint64: -1,
  279. SFixed32: 123400,
  280. SFixed64: 12,
  281. SSfixed32: -123400,
  282. SSfixed64: -12,
  283. },
  284. }, {
  285. desc: "integers in string",
  286. inputMessage: &pb3.Scalars{},
  287. inputText: `{
  288. "sInt32": "1234",
  289. "sInt64": "-1234",
  290. "sUint32": "1e2",
  291. "sUint64": "100E-2",
  292. "sSint32": "1.0",
  293. "sSint64": "-1.0",
  294. "sFixed32": "1.234e+5",
  295. "sFixed64": "1200E-2",
  296. "sSfixed32": "-1.234e05",
  297. "sSfixed64": "-1200e-02"
  298. }`,
  299. wantMessage: &pb3.Scalars{
  300. SInt32: 1234,
  301. SInt64: -1234,
  302. SUint32: 100,
  303. SUint64: 1,
  304. SSint32: 1,
  305. SSint64: -1,
  306. SFixed32: 123400,
  307. SFixed64: 12,
  308. SSfixed32: -123400,
  309. SSfixed64: -12,
  310. },
  311. }, {
  312. desc: "integers in escaped string",
  313. inputMessage: &pb3.Scalars{},
  314. inputText: `{"sInt32": "\u0031\u0032"}`,
  315. wantMessage: &pb3.Scalars{
  316. SInt32: 12,
  317. },
  318. }, {
  319. desc: "number is not an integer",
  320. inputMessage: &pb3.Scalars{},
  321. inputText: `{"sInt32": 1.001}`,
  322. wantErr: true,
  323. }, {
  324. desc: "32-bit int exceeds limit",
  325. inputMessage: &pb3.Scalars{},
  326. inputText: `{"sInt32": 2e10}`,
  327. wantErr: true,
  328. }, {
  329. desc: "64-bit int exceeds limit",
  330. inputMessage: &pb3.Scalars{},
  331. inputText: `{"sSfixed64": -9e19}`,
  332. wantErr: true,
  333. }, {
  334. desc: "not integer",
  335. inputMessage: &pb3.Scalars{},
  336. inputText: `{"sInt32": "not a number"}`,
  337. wantErr: true,
  338. }, {
  339. desc: "not unsigned integer",
  340. inputMessage: &pb3.Scalars{},
  341. inputText: `{"sUint32": "not a number"}`,
  342. wantErr: true,
  343. }, {
  344. desc: "number is not an unsigned integer",
  345. inputMessage: &pb3.Scalars{},
  346. inputText: `{"sUint32": -1}`,
  347. wantErr: true,
  348. }, {
  349. desc: "string",
  350. inputMessage: &pb2.Scalars{},
  351. inputText: `{"optString": "谷歌"}`,
  352. wantMessage: &pb2.Scalars{
  353. OptString: scalar.String("谷歌"),
  354. },
  355. }, {
  356. desc: "string with invalid UTF-8",
  357. inputMessage: &pb3.Scalars{},
  358. inputText: "{\"sString\": \"\xff\"}",
  359. wantMessage: &pb3.Scalars{
  360. SString: "\xff",
  361. },
  362. wantErr: true,
  363. }, {
  364. desc: "not string",
  365. inputMessage: &pb2.Scalars{},
  366. inputText: `{"optString": 42}`,
  367. wantErr: true,
  368. }, {
  369. desc: "bytes",
  370. inputMessage: &pb3.Scalars{},
  371. inputText: `{"sBytes": "aGVsbG8gd29ybGQ"}`,
  372. wantMessage: &pb3.Scalars{
  373. SBytes: []byte("hello world"),
  374. },
  375. }, {
  376. desc: "bytes padded",
  377. inputMessage: &pb3.Scalars{},
  378. inputText: `{"sBytes": "aGVsbG8gd29ybGQ="}`,
  379. wantMessage: &pb3.Scalars{
  380. SBytes: []byte("hello world"),
  381. },
  382. }, {
  383. desc: "not bytes",
  384. inputMessage: &pb3.Scalars{},
  385. inputText: `{"sBytes": true}`,
  386. wantErr: true,
  387. }, {
  388. desc: "proto2 enum",
  389. inputMessage: &pb2.Enums{},
  390. inputText: `{
  391. "optEnum": "ONE",
  392. "optNestedEnum": "UNO"
  393. }`,
  394. wantMessage: &pb2.Enums{
  395. OptEnum: pb2.Enum_ONE.Enum(),
  396. OptNestedEnum: pb2.Enums_UNO.Enum(),
  397. },
  398. }, {
  399. desc: "proto3 enum",
  400. inputMessage: &pb3.Enums{},
  401. inputText: `{
  402. "sEnum": "ONE",
  403. "sNestedEnum": "DIEZ"
  404. }`,
  405. wantMessage: &pb3.Enums{
  406. SEnum: pb3.Enum_ONE,
  407. SNestedEnum: pb3.Enums_DIEZ,
  408. },
  409. }, {
  410. desc: "enum numeric value",
  411. inputMessage: &pb3.Enums{},
  412. inputText: `{
  413. "sEnum": 2,
  414. "sNestedEnum": 2
  415. }`,
  416. wantMessage: &pb3.Enums{
  417. SEnum: pb3.Enum_TWO,
  418. SNestedEnum: pb3.Enums_DOS,
  419. },
  420. }, {
  421. desc: "enum unnamed numeric value",
  422. inputMessage: &pb3.Enums{},
  423. inputText: `{
  424. "sEnum": 101,
  425. "sNestedEnum": -101
  426. }`,
  427. wantMessage: &pb3.Enums{
  428. SEnum: 101,
  429. SNestedEnum: -101,
  430. },
  431. }, {
  432. desc: "enum set to number string",
  433. inputMessage: &pb3.Enums{},
  434. inputText: `{
  435. "sEnum": "1",
  436. }`,
  437. wantErr: true,
  438. }, {
  439. desc: "enum set to invalid named",
  440. inputMessage: &pb3.Enums{},
  441. inputText: `{
  442. "sEnum": "UNNAMED",
  443. }`,
  444. wantErr: true,
  445. }, {
  446. desc: "enum set to not enum",
  447. inputMessage: &pb3.Enums{},
  448. inputText: `{
  449. "sEnum": true,
  450. }`,
  451. wantErr: true,
  452. }, {
  453. desc: "proto name",
  454. inputMessage: &pb3.JSONNames{},
  455. inputText: `{
  456. "s_string": "proto name used"
  457. }`,
  458. wantMessage: &pb3.JSONNames{
  459. SString: "proto name used",
  460. },
  461. }, {
  462. desc: "json_name",
  463. inputMessage: &pb3.JSONNames{},
  464. inputText: `{
  465. "foo_bar": "json_name used"
  466. }`,
  467. wantMessage: &pb3.JSONNames{
  468. SString: "json_name used",
  469. },
  470. }, {
  471. desc: "camelCase name",
  472. inputMessage: &pb3.JSONNames{},
  473. inputText: `{
  474. "sString": "camelcase used"
  475. }`,
  476. wantErr: true,
  477. }, {
  478. desc: "proto name and json_name",
  479. inputMessage: &pb3.JSONNames{},
  480. inputText: `{
  481. "foo_bar": "json_name used",
  482. "s_string": "proto name used"
  483. }`,
  484. wantErr: true,
  485. }, {
  486. desc: "duplicate field names",
  487. inputMessage: &pb3.JSONNames{},
  488. inputText: `{
  489. "foo_bar": "one",
  490. "foo_bar": "two",
  491. }`,
  492. wantErr: true,
  493. }, {
  494. desc: "null message",
  495. inputMessage: &pb2.Nests{},
  496. inputText: "null",
  497. wantErr: true,
  498. }, {
  499. desc: "proto2 nested message not set",
  500. inputMessage: &pb2.Nests{},
  501. inputText: "{}",
  502. wantMessage: &pb2.Nests{},
  503. }, {
  504. desc: "proto2 nested message set to null",
  505. inputMessage: &pb2.Nests{},
  506. inputText: `{
  507. "optNested": null,
  508. "optgroup": null
  509. }`,
  510. wantMessage: &pb2.Nests{},
  511. }, {
  512. desc: "proto2 nested message set to empty",
  513. inputMessage: &pb2.Nests{},
  514. inputText: `{
  515. "optNested": {},
  516. "optgroup": {}
  517. }`,
  518. wantMessage: &pb2.Nests{
  519. OptNested: &pb2.Nested{},
  520. Optgroup: &pb2.Nests_OptGroup{},
  521. },
  522. }, {
  523. desc: "proto2 nested messages",
  524. inputMessage: &pb2.Nests{},
  525. inputText: `{
  526. "optNested": {
  527. "optString": "nested message",
  528. "optNested": {
  529. "optString": "another nested message"
  530. }
  531. }
  532. }`,
  533. wantMessage: &pb2.Nests{
  534. OptNested: &pb2.Nested{
  535. OptString: scalar.String("nested message"),
  536. OptNested: &pb2.Nested{
  537. OptString: scalar.String("another nested message"),
  538. },
  539. },
  540. },
  541. }, {
  542. desc: "proto2 groups",
  543. inputMessage: &pb2.Nests{},
  544. inputText: `{
  545. "optgroup": {
  546. "optString": "inside a group",
  547. "optNested": {
  548. "optString": "nested message inside a group"
  549. },
  550. "optnestedgroup": {
  551. "optFixed32": 47
  552. }
  553. }
  554. }`,
  555. wantMessage: &pb2.Nests{
  556. Optgroup: &pb2.Nests_OptGroup{
  557. OptString: scalar.String("inside a group"),
  558. OptNested: &pb2.Nested{
  559. OptString: scalar.String("nested message inside a group"),
  560. },
  561. Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
  562. OptFixed32: scalar.Uint32(47),
  563. },
  564. },
  565. },
  566. }, {
  567. desc: "proto3 nested message not set",
  568. inputMessage: &pb3.Nests{},
  569. inputText: "{}",
  570. wantMessage: &pb3.Nests{},
  571. }, {
  572. desc: "proto3 nested message set to null",
  573. inputMessage: &pb3.Nests{},
  574. inputText: `{"sNested": null}`,
  575. wantMessage: &pb3.Nests{},
  576. }, {
  577. desc: "proto3 nested message set to empty",
  578. inputMessage: &pb3.Nests{},
  579. inputText: `{"sNested": {}}`,
  580. wantMessage: &pb3.Nests{
  581. SNested: &pb3.Nested{},
  582. },
  583. }, {
  584. desc: "proto3 nested message",
  585. inputMessage: &pb3.Nests{},
  586. inputText: `{
  587. "sNested": {
  588. "sString": "nested message",
  589. "sNested": {
  590. "sString": "another nested message"
  591. }
  592. }
  593. }`,
  594. wantMessage: &pb3.Nests{
  595. SNested: &pb3.Nested{
  596. SString: "nested message",
  597. SNested: &pb3.Nested{
  598. SString: "another nested message",
  599. },
  600. },
  601. },
  602. }, {
  603. desc: "message set to non-message",
  604. inputMessage: &pb3.Nests{},
  605. inputText: `"not valid"`,
  606. wantErr: true,
  607. }, {
  608. desc: "nested message set to non-message",
  609. inputMessage: &pb3.Nests{},
  610. inputText: `{"sNested": true}`,
  611. wantErr: true,
  612. }, {
  613. desc: "oneof not set",
  614. inputMessage: &pb3.Oneofs{},
  615. inputText: "{}",
  616. wantMessage: &pb3.Oneofs{},
  617. }, {
  618. desc: "oneof set to empty string",
  619. inputMessage: &pb3.Oneofs{},
  620. inputText: `{"oneofString": ""}`,
  621. wantMessage: &pb3.Oneofs{
  622. Union: &pb3.Oneofs_OneofString{},
  623. },
  624. }, {
  625. desc: "oneof set to string",
  626. inputMessage: &pb3.Oneofs{},
  627. inputText: `{"oneofString": "hello"}`,
  628. wantMessage: &pb3.Oneofs{
  629. Union: &pb3.Oneofs_OneofString{
  630. OneofString: "hello",
  631. },
  632. },
  633. }, {
  634. desc: "oneof set to enum",
  635. inputMessage: &pb3.Oneofs{},
  636. inputText: `{"oneofEnum": "ZERO"}`,
  637. wantMessage: &pb3.Oneofs{
  638. Union: &pb3.Oneofs_OneofEnum{
  639. OneofEnum: pb3.Enum_ZERO,
  640. },
  641. },
  642. }, {
  643. desc: "oneof set to empty message",
  644. inputMessage: &pb3.Oneofs{},
  645. inputText: `{"oneofNested": {}}`,
  646. wantMessage: &pb3.Oneofs{
  647. Union: &pb3.Oneofs_OneofNested{
  648. OneofNested: &pb3.Nested{},
  649. },
  650. },
  651. }, {
  652. desc: "oneof set to message",
  653. inputMessage: &pb3.Oneofs{},
  654. inputText: `{
  655. "oneofNested": {
  656. "sString": "nested message"
  657. }
  658. }`,
  659. wantMessage: &pb3.Oneofs{
  660. Union: &pb3.Oneofs_OneofNested{
  661. OneofNested: &pb3.Nested{
  662. SString: "nested message",
  663. },
  664. },
  665. },
  666. }, {
  667. desc: "repeated null fields",
  668. inputMessage: &pb2.Repeats{},
  669. inputText: `{
  670. "rptString": null,
  671. "rptInt32" : null,
  672. "rptFloat" : null,
  673. "rptBytes" : null
  674. }`,
  675. wantMessage: &pb2.Repeats{},
  676. }, {
  677. desc: "repeated scalars",
  678. inputMessage: &pb2.Repeats{},
  679. inputText: `{
  680. "rptString": ["hello", "world"],
  681. "rptInt32" : [-1, 0, 1],
  682. "rptBool" : [false, true]
  683. }`,
  684. wantMessage: &pb2.Repeats{
  685. RptString: []string{"hello", "world"},
  686. RptInt32: []int32{-1, 0, 1},
  687. RptBool: []bool{false, true},
  688. },
  689. }, {
  690. desc: "repeated enums",
  691. inputMessage: &pb2.Enums{},
  692. inputText: `{
  693. "rptEnum" : ["TEN", 1, 42],
  694. "rptNestedEnum": ["DOS", 2, -47]
  695. }`,
  696. wantMessage: &pb2.Enums{
  697. RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
  698. RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
  699. },
  700. }, {
  701. desc: "repeated messages",
  702. inputMessage: &pb2.Nests{},
  703. inputText: `{
  704. "rptNested": [
  705. {
  706. "optString": "repeat nested one"
  707. },
  708. {
  709. "optString": "repeat nested two",
  710. "optNested": {
  711. "optString": "inside repeat nested two"
  712. }
  713. },
  714. {}
  715. ]
  716. }`,
  717. wantMessage: &pb2.Nests{
  718. RptNested: []*pb2.Nested{
  719. {
  720. OptString: scalar.String("repeat nested one"),
  721. },
  722. {
  723. OptString: scalar.String("repeat nested two"),
  724. OptNested: &pb2.Nested{
  725. OptString: scalar.String("inside repeat nested two"),
  726. },
  727. },
  728. {},
  729. },
  730. },
  731. }, {
  732. desc: "repeated groups",
  733. inputMessage: &pb2.Nests{},
  734. inputText: `{
  735. "rptgroup": [
  736. {
  737. "rptString": ["hello", "world"]
  738. },
  739. {}
  740. ]
  741. }
  742. `,
  743. wantMessage: &pb2.Nests{
  744. Rptgroup: []*pb2.Nests_RptGroup{
  745. {
  746. RptString: []string{"hello", "world"},
  747. },
  748. {},
  749. },
  750. },
  751. }, {
  752. desc: "repeated string contains invalid UTF8",
  753. inputMessage: &pb2.Repeats{},
  754. inputText: `{"rptString": ["` + "abc\xff" + `"]}`,
  755. wantMessage: &pb2.Repeats{
  756. RptString: []string{"abc\xff"},
  757. },
  758. wantErr: true,
  759. }, {
  760. desc: "repeated messages contain invalid UTF8",
  761. inputMessage: &pb2.Nests{},
  762. inputText: `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
  763. wantMessage: &pb2.Nests{
  764. RptNested: []*pb2.Nested{{OptString: scalar.String("abc\xff")}},
  765. },
  766. wantErr: true,
  767. }, {
  768. desc: "repeated scalars contain invalid type",
  769. inputMessage: &pb2.Repeats{},
  770. inputText: `{"rptString": ["hello", null, "world"]}`,
  771. wantErr: true,
  772. }, {
  773. desc: "repeated messages contain invalid type",
  774. inputMessage: &pb2.Nests{},
  775. inputText: `{"rptNested": [{}, null]}`,
  776. wantErr: true,
  777. }, {
  778. desc: "map fields 1",
  779. inputMessage: &pb3.Maps{},
  780. inputText: `{
  781. "int32ToStr": {
  782. "-101": "-101",
  783. "0" : "zero",
  784. "255" : "0xff"
  785. },
  786. "boolToUint32": {
  787. "false": 101,
  788. "true" : "42"
  789. }
  790. }`,
  791. wantMessage: &pb3.Maps{
  792. Int32ToStr: map[int32]string{
  793. -101: "-101",
  794. 0xff: "0xff",
  795. 0: "zero",
  796. },
  797. BoolToUint32: map[bool]uint32{
  798. true: 42,
  799. false: 101,
  800. },
  801. },
  802. }, {
  803. desc: "map fields 2",
  804. inputMessage: &pb3.Maps{},
  805. inputText: `{
  806. "uint64ToEnum": {
  807. "1" : "ONE",
  808. "2" : 2,
  809. "10": 101
  810. }
  811. }`,
  812. wantMessage: &pb3.Maps{
  813. Uint64ToEnum: map[uint64]pb3.Enum{
  814. 1: pb3.Enum_ONE,
  815. 2: pb3.Enum_TWO,
  816. 10: 101,
  817. },
  818. },
  819. }, {
  820. desc: "map fields 3",
  821. inputMessage: &pb3.Maps{},
  822. inputText: `{
  823. "strToNested": {
  824. "nested_one": {
  825. "sString": "nested in a map"
  826. },
  827. "nested_two": {}
  828. }
  829. }`,
  830. wantMessage: &pb3.Maps{
  831. StrToNested: map[string]*pb3.Nested{
  832. "nested_one": {
  833. SString: "nested in a map",
  834. },
  835. "nested_two": {},
  836. },
  837. },
  838. }, {
  839. desc: "map fields 4",
  840. inputMessage: &pb3.Maps{},
  841. inputText: `{
  842. "strToOneofs": {
  843. "nested": {
  844. "oneofNested": {
  845. "sString": "nested oneof in map field value"
  846. }
  847. },
  848. "string": {
  849. "oneofString": "hello"
  850. }
  851. }
  852. }`,
  853. wantMessage: &pb3.Maps{
  854. StrToOneofs: map[string]*pb3.Oneofs{
  855. "string": {
  856. Union: &pb3.Oneofs_OneofString{
  857. OneofString: "hello",
  858. },
  859. },
  860. "nested": {
  861. Union: &pb3.Oneofs_OneofNested{
  862. OneofNested: &pb3.Nested{
  863. SString: "nested oneof in map field value",
  864. },
  865. },
  866. },
  867. },
  868. },
  869. }, {
  870. desc: "map contains duplicate keys",
  871. inputMessage: &pb3.Maps{},
  872. inputText: `{
  873. "int32ToStr": {
  874. "0": "cero",
  875. "0": "zero"
  876. }
  877. }
  878. `,
  879. wantErr: true,
  880. }, {
  881. desc: "map key empty string",
  882. inputMessage: &pb3.Maps{},
  883. inputText: `{
  884. "strToNested": {
  885. "": {}
  886. }
  887. }`,
  888. wantMessage: &pb3.Maps{
  889. StrToNested: map[string]*pb3.Nested{
  890. "": {},
  891. },
  892. },
  893. }, {
  894. desc: "map contains invalid key 1",
  895. inputMessage: &pb3.Maps{},
  896. inputText: `{
  897. "int32ToStr": {
  898. "invalid": "cero"
  899. }`,
  900. wantErr: true,
  901. }, {
  902. desc: "map contains invalid key 2",
  903. inputMessage: &pb3.Maps{},
  904. inputText: `{
  905. "int32ToStr": {
  906. "1.02": "float"
  907. }`,
  908. wantErr: true,
  909. }, {
  910. desc: "map contains invalid key 3",
  911. inputMessage: &pb3.Maps{},
  912. inputText: `{
  913. "int32ToStr": {
  914. "2147483648": "exceeds 32-bit integer max limit"
  915. }`,
  916. wantErr: true,
  917. }, {
  918. desc: "map contains invalid key 4",
  919. inputMessage: &pb3.Maps{},
  920. inputText: `{
  921. "uint64ToEnum": {
  922. "-1": 0
  923. }
  924. }`,
  925. wantErr: true,
  926. }, {
  927. desc: "map contains invalid value",
  928. inputMessage: &pb3.Maps{},
  929. inputText: `{
  930. "int32ToStr": {
  931. "101": true
  932. }`,
  933. wantErr: true,
  934. }, {
  935. desc: "map contains null for scalar value",
  936. inputMessage: &pb3.Maps{},
  937. inputText: `{
  938. "int32ToStr": {
  939. "101": null
  940. }`,
  941. wantErr: true,
  942. }, {
  943. desc: "map contains null for message value",
  944. inputMessage: &pb3.Maps{},
  945. inputText: `{
  946. "strToNested": {
  947. "hello": null
  948. }
  949. }`,
  950. wantErr: true,
  951. }, {
  952. desc: "map contains contains message value with invalid UTF8",
  953. inputMessage: &pb3.Maps{},
  954. inputText: `{
  955. "strToNested": {
  956. "hello": {
  957. "sString": "` + "abc\xff" + `"
  958. }
  959. }
  960. }`,
  961. wantMessage: &pb3.Maps{
  962. StrToNested: map[string]*pb3.Nested{
  963. "hello": {SString: "abc\xff"},
  964. },
  965. },
  966. wantErr: true,
  967. }, {
  968. desc: "map key contains invalid UTF8",
  969. inputMessage: &pb3.Maps{},
  970. inputText: `{
  971. "strToNested": {
  972. "` + "abc\xff" + `": {}
  973. }
  974. }`,
  975. wantMessage: &pb3.Maps{
  976. StrToNested: map[string]*pb3.Nested{
  977. "abc\xff": {},
  978. },
  979. },
  980. wantErr: true,
  981. }, {
  982. desc: "extensions of non-repeated fields",
  983. inputMessage: &pb2.Extensions{},
  984. inputText: `{
  985. "optString": "non-extension field",
  986. "optBool": true,
  987. "optInt32": 42,
  988. "[pb2.opt_ext_bool]": true,
  989. "[pb2.opt_ext_nested]": {
  990. "optString": "nested in an extension",
  991. "optNested": {
  992. "optString": "another nested in an extension"
  993. }
  994. },
  995. "[pb2.opt_ext_string]": "extension field",
  996. "[pb2.opt_ext_enum]": "TEN"
  997. }`,
  998. wantMessage: func() proto.Message {
  999. m := &pb2.Extensions{
  1000. OptString: scalar.String("non-extension field"),
  1001. OptBool: scalar.Bool(true),
  1002. OptInt32: scalar.Int32(42),
  1003. }
  1004. setExtension(m, pb2.E_OptExtBool, true)
  1005. setExtension(m, pb2.E_OptExtString, "extension field")
  1006. setExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
  1007. setExtension(m, pb2.E_OptExtNested, &pb2.Nested{
  1008. OptString: scalar.String("nested in an extension"),
  1009. OptNested: &pb2.Nested{
  1010. OptString: scalar.String("another nested in an extension"),
  1011. },
  1012. })
  1013. return m
  1014. }(),
  1015. }, {
  1016. desc: "extensions of repeated fields",
  1017. inputMessage: &pb2.Extensions{},
  1018. inputText: `{
  1019. "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
  1020. "[pb2.rpt_ext_fixed32]": [42, 47],
  1021. "[pb2.rpt_ext_nested]": [
  1022. {"optString": "one"},
  1023. {"optString": "two"},
  1024. {"optString": "three"}
  1025. ]
  1026. }`,
  1027. wantMessage: func() proto.Message {
  1028. m := &pb2.Extensions{}
  1029. setExtension(m, pb2.E_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
  1030. setExtension(m, pb2.E_RptExtFixed32, &[]uint32{42, 47})
  1031. setExtension(m, pb2.E_RptExtNested, &[]*pb2.Nested{
  1032. &pb2.Nested{OptString: scalar.String("one")},
  1033. &pb2.Nested{OptString: scalar.String("two")},
  1034. &pb2.Nested{OptString: scalar.String("three")},
  1035. })
  1036. return m
  1037. }(),
  1038. }, {
  1039. desc: "extensions of non-repeated fields in another message",
  1040. inputMessage: &pb2.Extensions{},
  1041. inputText: `{
  1042. "[pb2.ExtensionsContainer.opt_ext_bool]": true,
  1043. "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
  1044. "[pb2.ExtensionsContainer.opt_ext_nested]": {
  1045. "optString": "nested in an extension",
  1046. "optNested": {
  1047. "optString": "another nested in an extension"
  1048. }
  1049. },
  1050. "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
  1051. }`,
  1052. wantMessage: func() proto.Message {
  1053. m := &pb2.Extensions{}
  1054. setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
  1055. setExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
  1056. setExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
  1057. setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
  1058. OptString: scalar.String("nested in an extension"),
  1059. OptNested: &pb2.Nested{
  1060. OptString: scalar.String("another nested in an extension"),
  1061. },
  1062. })
  1063. return m
  1064. }(),
  1065. }, {
  1066. desc: "extensions of repeated fields in another message",
  1067. inputMessage: &pb2.Extensions{},
  1068. inputText: `{
  1069. "optString": "non-extension field",
  1070. "optBool": true,
  1071. "optInt32": 42,
  1072. "[pb2.ExtensionsContainer.rpt_ext_nested]": [
  1073. {"optString": "one"},
  1074. {"optString": "two"},
  1075. {"optString": "three"}
  1076. ],
  1077. "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
  1078. "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
  1079. }`,
  1080. wantMessage: func() proto.Message {
  1081. m := &pb2.Extensions{
  1082. OptString: scalar.String("non-extension field"),
  1083. OptBool: scalar.Bool(true),
  1084. OptInt32: scalar.Int32(42),
  1085. }
  1086. setExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, &[]pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
  1087. setExtension(m, pb2.E_ExtensionsContainer_RptExtString, &[]string{"hello", "world"})
  1088. setExtension(m, pb2.E_ExtensionsContainer_RptExtNested, &[]*pb2.Nested{
  1089. &pb2.Nested{OptString: scalar.String("one")},
  1090. &pb2.Nested{OptString: scalar.String("two")},
  1091. &pb2.Nested{OptString: scalar.String("three")},
  1092. })
  1093. return m
  1094. }(),
  1095. }, {
  1096. desc: "invalid extension field name",
  1097. inputMessage: &pb2.Extensions{},
  1098. inputText: `{ "[pb2.invalid_message_field]": true }`,
  1099. wantErr: true,
  1100. }, {
  1101. desc: "MessageSet",
  1102. inputMessage: &pb2.MessageSet{},
  1103. inputText: `{
  1104. "[pb2.MessageSetExtension]": {
  1105. "optString": "a messageset extension"
  1106. },
  1107. "[pb2.MessageSetExtension.ext_nested]": {
  1108. "optString": "just a regular extension"
  1109. },
  1110. "[pb2.MessageSetExtension.not_message_set_extension]": {
  1111. "optString": "not a messageset extension"
  1112. }
  1113. }`,
  1114. wantMessage: func() proto.Message {
  1115. m := &pb2.MessageSet{}
  1116. setExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
  1117. OptString: scalar.String("a messageset extension"),
  1118. })
  1119. setExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
  1120. OptString: scalar.String("not a messageset extension"),
  1121. })
  1122. setExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
  1123. OptString: scalar.String("just a regular extension"),
  1124. })
  1125. return m
  1126. }(),
  1127. }, {
  1128. desc: "extension field set to null",
  1129. inputMessage: &pb2.Extensions{},
  1130. inputText: `{
  1131. "[pb2.ExtensionsContainer.opt_ext_bool]": null,
  1132. "[pb2.ExtensionsContainer.opt_ext_nested]": null
  1133. }`,
  1134. wantMessage: func() proto.Message {
  1135. m := &pb2.Extensions{}
  1136. setExtension(m, pb2.E_ExtensionsContainer_OptExtBool, nil)
  1137. setExtension(m, pb2.E_ExtensionsContainer_OptExtNested, nil)
  1138. return m
  1139. }(),
  1140. }, {
  1141. desc: "extensions of repeated field contains null",
  1142. inputMessage: &pb2.Extensions{},
  1143. inputText: `{
  1144. "[pb2.ExtensionsContainer.rpt_ext_nested]": [
  1145. {"optString": "one"},
  1146. null,
  1147. {"optString": "three"}
  1148. ],
  1149. }`,
  1150. wantErr: true,
  1151. }, {
  1152. desc: "not real MessageSet 1",
  1153. inputMessage: &pb2.FakeMessageSet{},
  1154. inputText: `{
  1155. "[pb2.FakeMessageSetExtension.message_set_extension]": {
  1156. "optString": "not a messageset extension"
  1157. }
  1158. }`,
  1159. wantMessage: func() proto.Message {
  1160. m := &pb2.FakeMessageSet{}
  1161. setExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
  1162. OptString: scalar.String("not a messageset extension"),
  1163. })
  1164. return m
  1165. }(),
  1166. }, {
  1167. desc: "not real MessageSet 2",
  1168. inputMessage: &pb2.FakeMessageSet{},
  1169. inputText: `{
  1170. "[pb2.FakeMessageSetExtension]": {
  1171. "optString": "not a messageset extension"
  1172. }
  1173. }`,
  1174. wantErr: true,
  1175. }, {
  1176. desc: "not real MessageSet 3",
  1177. inputMessage: &pb2.MessageSet{},
  1178. inputText: `{
  1179. "[pb2.message_set_extension]": {
  1180. "optString": "another not a messageset extension"
  1181. }
  1182. }`,
  1183. wantMessage: func() proto.Message {
  1184. m := &pb2.MessageSet{}
  1185. setExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
  1186. OptString: scalar.String("another not a messageset extension"),
  1187. })
  1188. return m
  1189. }(),
  1190. }, {
  1191. desc: "Empty",
  1192. inputMessage: &knownpb.Empty{},
  1193. inputText: `{}`,
  1194. wantMessage: &knownpb.Empty{},
  1195. }, {
  1196. desc: "Empty contains unknown",
  1197. inputMessage: &knownpb.Empty{},
  1198. inputText: `{"unknown": null}`,
  1199. wantErr: true,
  1200. }, {
  1201. desc: "BoolValue false",
  1202. inputMessage: &knownpb.BoolValue{},
  1203. inputText: `false`,
  1204. wantMessage: &knownpb.BoolValue{},
  1205. }, {
  1206. desc: "BoolValue true",
  1207. inputMessage: &knownpb.BoolValue{},
  1208. inputText: `true`,
  1209. wantMessage: &knownpb.BoolValue{Value: true},
  1210. }, {
  1211. desc: "BoolValue invalid value",
  1212. inputMessage: &knownpb.BoolValue{},
  1213. inputText: `{}`,
  1214. wantErr: true,
  1215. }, {
  1216. desc: "Int32Value",
  1217. inputMessage: &knownpb.Int32Value{},
  1218. inputText: `42`,
  1219. wantMessage: &knownpb.Int32Value{Value: 42},
  1220. }, {
  1221. desc: "Int32Value in JSON string",
  1222. inputMessage: &knownpb.Int32Value{},
  1223. inputText: `"1.23e3"`,
  1224. wantMessage: &knownpb.Int32Value{Value: 1230},
  1225. }, {
  1226. desc: "Int64Value",
  1227. inputMessage: &knownpb.Int64Value{},
  1228. inputText: `"42"`,
  1229. wantMessage: &knownpb.Int64Value{Value: 42},
  1230. }, {
  1231. desc: "UInt32Value",
  1232. inputMessage: &knownpb.UInt32Value{},
  1233. inputText: `42`,
  1234. wantMessage: &knownpb.UInt32Value{Value: 42},
  1235. }, {
  1236. desc: "UInt64Value",
  1237. inputMessage: &knownpb.UInt64Value{},
  1238. inputText: `"42"`,
  1239. wantMessage: &knownpb.UInt64Value{Value: 42},
  1240. }, {
  1241. desc: "FloatValue",
  1242. inputMessage: &knownpb.FloatValue{},
  1243. inputText: `1.02`,
  1244. wantMessage: &knownpb.FloatValue{Value: 1.02},
  1245. }, {
  1246. desc: "FloatValue exceeds max limit",
  1247. inputMessage: &knownpb.FloatValue{},
  1248. inputText: `1.23+40`,
  1249. wantErr: true,
  1250. }, {
  1251. desc: "FloatValue Infinity",
  1252. inputMessage: &knownpb.FloatValue{},
  1253. inputText: `"-Infinity"`,
  1254. wantMessage: &knownpb.FloatValue{Value: float32(math.Inf(-1))},
  1255. }, {
  1256. desc: "DoubleValue",
  1257. inputMessage: &knownpb.DoubleValue{},
  1258. inputText: `1.02`,
  1259. wantMessage: &knownpb.DoubleValue{Value: 1.02},
  1260. }, {
  1261. desc: "DoubleValue Infinity",
  1262. inputMessage: &knownpb.DoubleValue{},
  1263. inputText: `"Infinity"`,
  1264. wantMessage: &knownpb.DoubleValue{Value: math.Inf(+1)},
  1265. }, {
  1266. desc: "StringValue empty",
  1267. inputMessage: &knownpb.StringValue{},
  1268. inputText: `""`,
  1269. wantMessage: &knownpb.StringValue{},
  1270. }, {
  1271. desc: "StringValue",
  1272. inputMessage: &knownpb.StringValue{},
  1273. inputText: `"谷歌"`,
  1274. wantMessage: &knownpb.StringValue{Value: "谷歌"},
  1275. }, {
  1276. desc: "StringValue with invalid UTF8 error",
  1277. inputMessage: &knownpb.StringValue{},
  1278. inputText: "\"abc\xff\"",
  1279. wantMessage: &knownpb.StringValue{Value: "abc\xff"},
  1280. wantErr: true,
  1281. }, {
  1282. desc: "StringValue field with invalid UTF8 error",
  1283. inputMessage: &pb2.KnownTypes{},
  1284. inputText: "{\n \"optString\": \"abc\xff\"\n}",
  1285. wantMessage: &pb2.KnownTypes{
  1286. OptString: &knownpb.StringValue{Value: "abc\xff"},
  1287. },
  1288. wantErr: true,
  1289. }, {
  1290. desc: "BytesValue",
  1291. inputMessage: &knownpb.BytesValue{},
  1292. inputText: `"aGVsbG8="`,
  1293. wantMessage: &knownpb.BytesValue{Value: []byte("hello")},
  1294. }, {
  1295. desc: "Value null",
  1296. inputMessage: &knownpb.Value{},
  1297. inputText: `null`,
  1298. wantMessage: &knownpb.Value{Kind: &knownpb.Value_NullValue{}},
  1299. }, {
  1300. desc: "Value field null",
  1301. inputMessage: &pb2.KnownTypes{},
  1302. inputText: `{
  1303. "optValue": null
  1304. }`,
  1305. wantMessage: &pb2.KnownTypes{
  1306. OptValue: &knownpb.Value{Kind: &knownpb.Value_NullValue{}},
  1307. },
  1308. }, {
  1309. desc: "Value bool",
  1310. inputMessage: &knownpb.Value{},
  1311. inputText: `false`,
  1312. wantMessage: &knownpb.Value{Kind: &knownpb.Value_BoolValue{}},
  1313. }, {
  1314. desc: "Value field bool",
  1315. inputMessage: &pb2.KnownTypes{},
  1316. inputText: `{
  1317. "optValue": true
  1318. }`,
  1319. wantMessage: &pb2.KnownTypes{
  1320. OptValue: &knownpb.Value{Kind: &knownpb.Value_BoolValue{true}},
  1321. },
  1322. }, {
  1323. desc: "Value number",
  1324. inputMessage: &knownpb.Value{},
  1325. inputText: `1.02`,
  1326. wantMessage: &knownpb.Value{Kind: &knownpb.Value_NumberValue{1.02}},
  1327. }, {
  1328. desc: "Value field number",
  1329. inputMessage: &pb2.KnownTypes{},
  1330. inputText: `{
  1331. "optValue": 1.02
  1332. }`,
  1333. wantMessage: &pb2.KnownTypes{
  1334. OptValue: &knownpb.Value{Kind: &knownpb.Value_NumberValue{1.02}},
  1335. },
  1336. }, {
  1337. desc: "Value string",
  1338. inputMessage: &knownpb.Value{},
  1339. inputText: `"hello"`,
  1340. wantMessage: &knownpb.Value{Kind: &knownpb.Value_StringValue{"hello"}},
  1341. }, {
  1342. desc: "Value string with invalid UTF8",
  1343. inputMessage: &knownpb.Value{},
  1344. inputText: "\"\xff\"",
  1345. wantMessage: &knownpb.Value{Kind: &knownpb.Value_StringValue{"\xff"}},
  1346. wantErr: true,
  1347. }, {
  1348. desc: "Value field string",
  1349. inputMessage: &pb2.KnownTypes{},
  1350. inputText: `{
  1351. "optValue": "NaN"
  1352. }`,
  1353. wantMessage: &pb2.KnownTypes{
  1354. OptValue: &knownpb.Value{Kind: &knownpb.Value_StringValue{"NaN"}},
  1355. },
  1356. }, {
  1357. desc: "Value field string with invalid UTF8",
  1358. inputMessage: &pb2.KnownTypes{},
  1359. inputText: `{
  1360. "optValue": "` + "\xff" + `"
  1361. }`,
  1362. wantMessage: &pb2.KnownTypes{
  1363. OptValue: &knownpb.Value{Kind: &knownpb.Value_StringValue{"\xff"}},
  1364. },
  1365. wantErr: true,
  1366. }, {
  1367. desc: "Value empty struct",
  1368. inputMessage: &knownpb.Value{},
  1369. inputText: `{}`,
  1370. wantMessage: &knownpb.Value{
  1371. Kind: &knownpb.Value_StructValue{
  1372. &knownpb.Struct{Fields: map[string]*knownpb.Value{}},
  1373. },
  1374. },
  1375. }, {
  1376. desc: "Value struct",
  1377. inputMessage: &knownpb.Value{},
  1378. inputText: `{
  1379. "string": "hello",
  1380. "number": 123,
  1381. "null": null,
  1382. "bool": false,
  1383. "struct": {
  1384. "string": "world"
  1385. },
  1386. "list": []
  1387. }`,
  1388. wantMessage: &knownpb.Value{
  1389. Kind: &knownpb.Value_StructValue{
  1390. &knownpb.Struct{
  1391. Fields: map[string]*knownpb.Value{
  1392. "string": {Kind: &knownpb.Value_StringValue{"hello"}},
  1393. "number": {Kind: &knownpb.Value_NumberValue{123}},
  1394. "null": {Kind: &knownpb.Value_NullValue{}},
  1395. "bool": {Kind: &knownpb.Value_BoolValue{false}},
  1396. "struct": {
  1397. Kind: &knownpb.Value_StructValue{
  1398. &knownpb.Struct{
  1399. Fields: map[string]*knownpb.Value{
  1400. "string": {Kind: &knownpb.Value_StringValue{"world"}},
  1401. },
  1402. },
  1403. },
  1404. },
  1405. "list": {
  1406. Kind: &knownpb.Value_ListValue{&knownpb.ListValue{}},
  1407. },
  1408. },
  1409. },
  1410. },
  1411. },
  1412. }, {
  1413. desc: "Value struct with invalid UTF8 string",
  1414. inputMessage: &knownpb.Value{},
  1415. inputText: "{\"string\": \"abc\xff\"}",
  1416. wantMessage: &knownpb.Value{
  1417. Kind: &knownpb.Value_StructValue{
  1418. &knownpb.Struct{
  1419. Fields: map[string]*knownpb.Value{
  1420. "string": {Kind: &knownpb.Value_StringValue{"abc\xff"}},
  1421. },
  1422. },
  1423. },
  1424. },
  1425. wantErr: true,
  1426. }, {
  1427. desc: "Value field struct",
  1428. inputMessage: &pb2.KnownTypes{},
  1429. inputText: `{
  1430. "optValue": {
  1431. "string": "hello"
  1432. }
  1433. }`,
  1434. wantMessage: &pb2.KnownTypes{
  1435. OptValue: &knownpb.Value{
  1436. Kind: &knownpb.Value_StructValue{
  1437. &knownpb.Struct{
  1438. Fields: map[string]*knownpb.Value{
  1439. "string": {Kind: &knownpb.Value_StringValue{"hello"}},
  1440. },
  1441. },
  1442. },
  1443. },
  1444. },
  1445. }, {
  1446. desc: "Value empty list",
  1447. inputMessage: &knownpb.Value{},
  1448. inputText: `[]`,
  1449. wantMessage: &knownpb.Value{
  1450. Kind: &knownpb.Value_ListValue{
  1451. &knownpb.ListValue{Values: []*knownpb.Value{}},
  1452. },
  1453. },
  1454. }, {
  1455. desc: "Value list",
  1456. inputMessage: &knownpb.Value{},
  1457. inputText: `[
  1458. "string",
  1459. 123,
  1460. null,
  1461. true,
  1462. {},
  1463. [
  1464. "string",
  1465. 1.23,
  1466. null,
  1467. false
  1468. ]
  1469. ]`,
  1470. wantMessage: &knownpb.Value{
  1471. Kind: &knownpb.Value_ListValue{
  1472. &knownpb.ListValue{
  1473. Values: []*knownpb.Value{
  1474. {Kind: &knownpb.Value_StringValue{"string"}},
  1475. {Kind: &knownpb.Value_NumberValue{123}},
  1476. {Kind: &knownpb.Value_NullValue{}},
  1477. {Kind: &knownpb.Value_BoolValue{true}},
  1478. {Kind: &knownpb.Value_StructValue{&knownpb.Struct{}}},
  1479. {
  1480. Kind: &knownpb.Value_ListValue{
  1481. &knownpb.ListValue{
  1482. Values: []*knownpb.Value{
  1483. {Kind: &knownpb.Value_StringValue{"string"}},
  1484. {Kind: &knownpb.Value_NumberValue{1.23}},
  1485. {Kind: &knownpb.Value_NullValue{}},
  1486. {Kind: &knownpb.Value_BoolValue{false}},
  1487. },
  1488. },
  1489. },
  1490. },
  1491. },
  1492. },
  1493. },
  1494. },
  1495. }, {
  1496. desc: "Value list with invalid UTF8 string",
  1497. inputMessage: &knownpb.Value{},
  1498. inputText: "[\"abc\xff\"]",
  1499. wantMessage: &knownpb.Value{
  1500. Kind: &knownpb.Value_ListValue{
  1501. &knownpb.ListValue{
  1502. Values: []*knownpb.Value{
  1503. {Kind: &knownpb.Value_StringValue{"abc\xff"}},
  1504. },
  1505. },
  1506. },
  1507. },
  1508. wantErr: true,
  1509. }, {
  1510. desc: "Value field list with invalid UTF8 string",
  1511. inputMessage: &pb2.KnownTypes{},
  1512. inputText: `{
  1513. "optValue": [ "` + "abc\xff" + `"]
  1514. }`,
  1515. wantMessage: &pb2.KnownTypes{
  1516. OptValue: &knownpb.Value{
  1517. Kind: &knownpb.Value_ListValue{
  1518. &knownpb.ListValue{
  1519. Values: []*knownpb.Value{
  1520. {Kind: &knownpb.Value_StringValue{"abc\xff"}},
  1521. },
  1522. },
  1523. },
  1524. },
  1525. },
  1526. wantErr: true,
  1527. }, {
  1528. desc: "Duration empty string",
  1529. inputMessage: &knownpb.Duration{},
  1530. inputText: `""`,
  1531. wantErr: true,
  1532. }, {
  1533. desc: "Duration with secs",
  1534. inputMessage: &knownpb.Duration{},
  1535. inputText: `"3s"`,
  1536. wantMessage: &knownpb.Duration{Seconds: 3},
  1537. }, {
  1538. desc: "Duration with escaped unicode",
  1539. inputMessage: &knownpb.Duration{},
  1540. inputText: `"\u0033s"`,
  1541. wantMessage: &knownpb.Duration{Seconds: 3},
  1542. }, {
  1543. desc: "Duration with -secs",
  1544. inputMessage: &knownpb.Duration{},
  1545. inputText: `"-3s"`,
  1546. wantMessage: &knownpb.Duration{Seconds: -3},
  1547. }, {
  1548. desc: "Duration with nanos",
  1549. inputMessage: &knownpb.Duration{},
  1550. inputText: `"0.001s"`,
  1551. wantMessage: &knownpb.Duration{Nanos: 1e6},
  1552. }, {
  1553. desc: "Duration with -nanos",
  1554. inputMessage: &knownpb.Duration{},
  1555. inputText: `"-0.001s"`,
  1556. wantMessage: &knownpb.Duration{Nanos: -1e6},
  1557. }, {
  1558. desc: "Duration with -secs -nanos",
  1559. inputMessage: &knownpb.Duration{},
  1560. inputText: `"-123.000000450s"`,
  1561. wantMessage: &knownpb.Duration{Seconds: -123, Nanos: -450},
  1562. }, {
  1563. desc: "Duration with large secs",
  1564. inputMessage: &knownpb.Duration{},
  1565. inputText: `"10000000000.000000001s"`,
  1566. wantMessage: &knownpb.Duration{Seconds: 1e10, Nanos: 1},
  1567. }, {
  1568. desc: "Duration with decimal without fractional",
  1569. inputMessage: &knownpb.Duration{},
  1570. inputText: `"3.s"`,
  1571. wantMessage: &knownpb.Duration{Seconds: 3},
  1572. }, {
  1573. desc: "Duration with decimal without integer",
  1574. inputMessage: &knownpb.Duration{},
  1575. inputText: `"0.5s"`,
  1576. wantMessage: &knownpb.Duration{Nanos: 5e8},
  1577. }, {
  1578. desc: "Duration with +secs out of range",
  1579. inputMessage: &knownpb.Duration{},
  1580. inputText: `"315576000001s"`,
  1581. wantErr: true,
  1582. }, {
  1583. desc: "Duration with -secs out of range",
  1584. inputMessage: &knownpb.Duration{},
  1585. inputText: `"-315576000001s"`,
  1586. wantErr: true,
  1587. }, {
  1588. desc: "Duration with nanos beyond 9 digits",
  1589. inputMessage: &knownpb.Duration{},
  1590. inputText: `"0.9999999990s"`,
  1591. wantErr: true,
  1592. }, {
  1593. desc: "Duration without suffix s",
  1594. inputMessage: &knownpb.Duration{},
  1595. inputText: `"123"`,
  1596. wantErr: true,
  1597. }, {
  1598. desc: "Timestamp zero",
  1599. inputMessage: &knownpb.Timestamp{},
  1600. inputText: `"1970-01-01T00:00:00Z"`,
  1601. wantMessage: &knownpb.Timestamp{},
  1602. }, {
  1603. desc: "Timestamp with tz adjustment",
  1604. inputMessage: &knownpb.Timestamp{},
  1605. inputText: `"1970-01-01T00:00:00+01:00"`,
  1606. wantMessage: &knownpb.Timestamp{Seconds: -3600},
  1607. }, {
  1608. desc: "Timestamp UTC",
  1609. inputMessage: &knownpb.Timestamp{},
  1610. inputText: `"2019-03-19T23:03:21Z"`,
  1611. wantMessage: &knownpb.Timestamp{Seconds: 1553036601},
  1612. }, {
  1613. desc: "Timestamp with escaped unicode",
  1614. inputMessage: &knownpb.Timestamp{},
  1615. inputText: `"2019-0\u0033-19T23:03:21Z"`,
  1616. wantMessage: &knownpb.Timestamp{Seconds: 1553036601},
  1617. }, {
  1618. desc: "Timestamp with nanos",
  1619. inputMessage: &knownpb.Timestamp{},
  1620. inputText: `"2019-03-19T23:03:21.000000001Z"`,
  1621. wantMessage: &knownpb.Timestamp{Seconds: 1553036601, Nanos: 1},
  1622. }, {
  1623. desc: "Timestamp upper limit",
  1624. inputMessage: &knownpb.Timestamp{},
  1625. inputText: `"9999-12-31T23:59:59.999999999Z"`,
  1626. wantMessage: &knownpb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
  1627. }, {
  1628. desc: "Timestamp above upper limit",
  1629. inputMessage: &knownpb.Timestamp{},
  1630. inputText: `"9999-12-31T23:59:59-01:00"`,
  1631. wantErr: true,
  1632. }, {
  1633. desc: "Timestamp lower limit",
  1634. inputMessage: &knownpb.Timestamp{},
  1635. inputText: `"0001-01-01T00:00:00Z"`,
  1636. wantMessage: &knownpb.Timestamp{Seconds: -62135596800},
  1637. }, {
  1638. desc: "Timestamp below lower limit",
  1639. inputMessage: &knownpb.Timestamp{},
  1640. inputText: `"0001-01-01T00:00:00+01:00"`,
  1641. wantErr: true,
  1642. }, {
  1643. desc: "Timestamp with nanos beyond 9 digits",
  1644. inputMessage: &knownpb.Timestamp{},
  1645. inputText: `"1970-01-01T00:00:00.0000000001Z"`,
  1646. wantErr: true,
  1647. }, {
  1648. desc: "FieldMask empty",
  1649. inputMessage: &knownpb.FieldMask{},
  1650. inputText: `""`,
  1651. wantMessage: &knownpb.FieldMask{Paths: []string{}},
  1652. }, {
  1653. desc: "FieldMask",
  1654. inputMessage: &knownpb.FieldMask{},
  1655. inputText: `"foo,fooBar , foo.barQux ,Foo"`,
  1656. wantMessage: &knownpb.FieldMask{
  1657. Paths: []string{
  1658. "foo",
  1659. "foo_bar",
  1660. "foo.bar_qux",
  1661. "_foo",
  1662. },
  1663. },
  1664. }, {
  1665. desc: "FieldMask field",
  1666. inputMessage: &pb2.KnownTypes{},
  1667. inputText: `{
  1668. "optFieldmask": "foo, qux.fooBar"
  1669. }`,
  1670. wantMessage: &pb2.KnownTypes{
  1671. OptFieldmask: &knownpb.FieldMask{
  1672. Paths: []string{
  1673. "foo",
  1674. "qux.foo_bar",
  1675. },
  1676. },
  1677. },
  1678. }}
  1679. for _, tt := range tests {
  1680. tt := tt
  1681. t.Run(tt.desc, func(t *testing.T) {
  1682. err := tt.umo.Unmarshal(tt.inputMessage, []byte(tt.inputText))
  1683. if err != nil && !tt.wantErr {
  1684. t.Errorf("Unmarshal() returned error: %v\n\n", err)
  1685. }
  1686. if err == nil && tt.wantErr {
  1687. t.Error("Unmarshal() got nil error, want error\n\n")
  1688. }
  1689. if tt.wantMessage != nil && !protoV1.Equal(tt.inputMessage.(protoV1.Message), tt.wantMessage.(protoV1.Message)) {
  1690. t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
  1691. }
  1692. })
  1693. }
  1694. }