decode_test.go 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421
  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 protojson_test
  5. import (
  6. "math"
  7. "testing"
  8. "google.golang.org/protobuf/encoding/protojson"
  9. "google.golang.org/protobuf/internal/flags"
  10. "google.golang.org/protobuf/proto"
  11. preg "google.golang.org/protobuf/reflect/protoregistry"
  12. "google.golang.org/protobuf/encoding/testprotos/pb2"
  13. "google.golang.org/protobuf/encoding/testprotos/pb3"
  14. testpb "google.golang.org/protobuf/internal/testprotos/test"
  15. weakpb "google.golang.org/protobuf/internal/testprotos/test/weak1"
  16. "google.golang.org/protobuf/types/known/anypb"
  17. "google.golang.org/protobuf/types/known/durationpb"
  18. "google.golang.org/protobuf/types/known/emptypb"
  19. "google.golang.org/protobuf/types/known/fieldmaskpb"
  20. "google.golang.org/protobuf/types/known/structpb"
  21. "google.golang.org/protobuf/types/known/timestamppb"
  22. "google.golang.org/protobuf/types/known/wrapperspb"
  23. )
  24. func TestUnmarshal(t *testing.T) {
  25. tests := []struct {
  26. desc string
  27. umo protojson.UnmarshalOptions
  28. inputMessage proto.Message
  29. inputText string
  30. wantMessage proto.Message
  31. // TODO: verify expected error message substring.
  32. wantErr bool
  33. skip bool
  34. }{{
  35. desc: "proto2 empty message",
  36. inputMessage: &pb2.Scalars{},
  37. inputText: "{}",
  38. wantMessage: &pb2.Scalars{},
  39. }, {
  40. desc: "unexpected value instead of EOF",
  41. inputMessage: &pb2.Scalars{},
  42. inputText: "{} {}",
  43. wantErr: true,
  44. }, {
  45. desc: "proto2 optional scalars set to zero values",
  46. inputMessage: &pb2.Scalars{},
  47. inputText: `{
  48. "optBool": false,
  49. "optInt32": 0,
  50. "optInt64": 0,
  51. "optUint32": 0,
  52. "optUint64": 0,
  53. "optSint32": 0,
  54. "optSint64": 0,
  55. "optFixed32": 0,
  56. "optFixed64": 0,
  57. "optSfixed32": 0,
  58. "optSfixed64": 0,
  59. "optFloat": 0,
  60. "optDouble": 0,
  61. "optBytes": "",
  62. "optString": ""
  63. }`,
  64. wantMessage: &pb2.Scalars{
  65. OptBool: proto.Bool(false),
  66. OptInt32: proto.Int32(0),
  67. OptInt64: proto.Int64(0),
  68. OptUint32: proto.Uint32(0),
  69. OptUint64: proto.Uint64(0),
  70. OptSint32: proto.Int32(0),
  71. OptSint64: proto.Int64(0),
  72. OptFixed32: proto.Uint32(0),
  73. OptFixed64: proto.Uint64(0),
  74. OptSfixed32: proto.Int32(0),
  75. OptSfixed64: proto.Int64(0),
  76. OptFloat: proto.Float32(0),
  77. OptDouble: proto.Float64(0),
  78. OptBytes: []byte{},
  79. OptString: proto.String(""),
  80. },
  81. }, {
  82. desc: "proto3 scalars set to zero values",
  83. inputMessage: &pb3.Scalars{},
  84. inputText: `{
  85. "sBool": false,
  86. "sInt32": 0,
  87. "sInt64": 0,
  88. "sUint32": 0,
  89. "sUint64": 0,
  90. "sSint32": 0,
  91. "sSint64": 0,
  92. "sFixed32": 0,
  93. "sFixed64": 0,
  94. "sSfixed32": 0,
  95. "sSfixed64": 0,
  96. "sFloat": 0,
  97. "sDouble": 0,
  98. "sBytes": "",
  99. "sString": ""
  100. }`,
  101. wantMessage: &pb3.Scalars{},
  102. }, {
  103. desc: "proto2 optional scalars set to null",
  104. inputMessage: &pb2.Scalars{},
  105. inputText: `{
  106. "optBool": null,
  107. "optInt32": null,
  108. "optInt64": null,
  109. "optUint32": null,
  110. "optUint64": null,
  111. "optSint32": null,
  112. "optSint64": null,
  113. "optFixed32": null,
  114. "optFixed64": null,
  115. "optSfixed32": null,
  116. "optSfixed64": null,
  117. "optFloat": null,
  118. "optDouble": null,
  119. "optBytes": null,
  120. "optString": null
  121. }`,
  122. wantMessage: &pb2.Scalars{},
  123. }, {
  124. desc: "proto3 scalars set to null",
  125. inputMessage: &pb3.Scalars{},
  126. inputText: `{
  127. "sBool": null,
  128. "sInt32": null,
  129. "sInt64": null,
  130. "sUint32": null,
  131. "sUint64": null,
  132. "sSint32": null,
  133. "sSint64": null,
  134. "sFixed32": null,
  135. "sFixed64": null,
  136. "sSfixed32": null,
  137. "sSfixed64": null,
  138. "sFloat": null,
  139. "sDouble": null,
  140. "sBytes": null,
  141. "sString": null
  142. }`,
  143. wantMessage: &pb3.Scalars{},
  144. }, {
  145. desc: "boolean",
  146. inputMessage: &pb3.Scalars{},
  147. inputText: `{"sBool": true}`,
  148. wantMessage: &pb3.Scalars{
  149. SBool: true,
  150. },
  151. }, {
  152. desc: "not boolean",
  153. inputMessage: &pb3.Scalars{},
  154. inputText: `{"sBool": "true"}`,
  155. wantErr: true,
  156. }, {
  157. desc: "float and double",
  158. inputMessage: &pb3.Scalars{},
  159. inputText: `{
  160. "sFloat": 1.234,
  161. "sDouble": 5.678
  162. }`,
  163. wantMessage: &pb3.Scalars{
  164. SFloat: 1.234,
  165. SDouble: 5.678,
  166. },
  167. }, {
  168. desc: "float and double in string",
  169. inputMessage: &pb3.Scalars{},
  170. inputText: `{
  171. "sFloat": "1.234",
  172. "sDouble": "5.678"
  173. }`,
  174. wantMessage: &pb3.Scalars{
  175. SFloat: 1.234,
  176. SDouble: 5.678,
  177. },
  178. }, {
  179. desc: "float and double in E notation",
  180. inputMessage: &pb3.Scalars{},
  181. inputText: `{
  182. "sFloat": 12.34E-1,
  183. "sDouble": 5.678e4
  184. }`,
  185. wantMessage: &pb3.Scalars{
  186. SFloat: 1.234,
  187. SDouble: 56780,
  188. },
  189. }, {
  190. desc: "float and double in string E notation",
  191. inputMessage: &pb3.Scalars{},
  192. inputText: `{
  193. "sFloat": "12.34E-1",
  194. "sDouble": "5.678e4"
  195. }`,
  196. wantMessage: &pb3.Scalars{
  197. SFloat: 1.234,
  198. SDouble: 56780,
  199. },
  200. }, {
  201. desc: "float exceeds limit",
  202. inputMessage: &pb3.Scalars{},
  203. inputText: `{"sFloat": 3.4e39}`,
  204. wantErr: true,
  205. }, {
  206. desc: "float in string exceeds limit",
  207. inputMessage: &pb3.Scalars{},
  208. inputText: `{"sFloat": "-3.4e39"}`,
  209. wantErr: true,
  210. }, {
  211. desc: "double exceeds limit",
  212. inputMessage: &pb3.Scalars{},
  213. inputText: `{"sFloat": -1.79e+309}`,
  214. wantErr: true,
  215. }, {
  216. desc: "double in string exceeds limit",
  217. inputMessage: &pb3.Scalars{},
  218. inputText: `{"sFloat": "1.79e+309"}`,
  219. wantErr: true,
  220. }, {
  221. desc: "infinites",
  222. inputMessage: &pb3.Scalars{},
  223. inputText: `{"sFloat": "Infinity", "sDouble": "-Infinity"}`,
  224. wantMessage: &pb3.Scalars{
  225. SFloat: float32(math.Inf(+1)),
  226. SDouble: math.Inf(-1),
  227. },
  228. }, {
  229. desc: "float string with leading space",
  230. inputMessage: &pb3.Scalars{},
  231. inputText: `{"sFloat": " 1.234"}`,
  232. wantErr: true,
  233. }, {
  234. desc: "double string with trailing space",
  235. inputMessage: &pb3.Scalars{},
  236. inputText: `{"sDouble": "5.678 "}`,
  237. wantErr: true,
  238. }, {
  239. desc: "not float",
  240. inputMessage: &pb3.Scalars{},
  241. inputText: `{"sFloat": true}`,
  242. wantErr: true,
  243. }, {
  244. desc: "not double",
  245. inputMessage: &pb3.Scalars{},
  246. inputText: `{"sDouble": "not a number"}`,
  247. wantErr: true,
  248. }, {
  249. desc: "integers",
  250. inputMessage: &pb3.Scalars{},
  251. inputText: `{
  252. "sInt32": 1234,
  253. "sInt64": -1234,
  254. "sUint32": 1e2,
  255. "sUint64": 100E-2,
  256. "sSint32": 1.0,
  257. "sSint64": -1.0,
  258. "sFixed32": 1.234e+5,
  259. "sFixed64": 1200E-2,
  260. "sSfixed32": -1.234e05,
  261. "sSfixed64": -1200e-02
  262. }`,
  263. wantMessage: &pb3.Scalars{
  264. SInt32: 1234,
  265. SInt64: -1234,
  266. SUint32: 100,
  267. SUint64: 1,
  268. SSint32: 1,
  269. SSint64: -1,
  270. SFixed32: 123400,
  271. SFixed64: 12,
  272. SSfixed32: -123400,
  273. SSfixed64: -12,
  274. },
  275. }, {
  276. desc: "integers in string",
  277. inputMessage: &pb3.Scalars{},
  278. inputText: `{
  279. "sInt32": "1234",
  280. "sInt64": "-1234",
  281. "sUint32": "1e2",
  282. "sUint64": "100E-2",
  283. "sSint32": "1.0",
  284. "sSint64": "-1.0",
  285. "sFixed32": "1.234e+5",
  286. "sFixed64": "1200E-2",
  287. "sSfixed32": "-1.234e05",
  288. "sSfixed64": "-1200e-02"
  289. }`,
  290. wantMessage: &pb3.Scalars{
  291. SInt32: 1234,
  292. SInt64: -1234,
  293. SUint32: 100,
  294. SUint64: 1,
  295. SSint32: 1,
  296. SSint64: -1,
  297. SFixed32: 123400,
  298. SFixed64: 12,
  299. SSfixed32: -123400,
  300. SSfixed64: -12,
  301. },
  302. }, {
  303. desc: "integers in escaped string",
  304. inputMessage: &pb3.Scalars{},
  305. inputText: `{"sInt32": "\u0031\u0032"}`,
  306. wantMessage: &pb3.Scalars{
  307. SInt32: 12,
  308. },
  309. }, {
  310. desc: "integer string with leading space",
  311. inputMessage: &pb3.Scalars{},
  312. inputText: `{"sInt32": " 1234"}`,
  313. wantErr: true,
  314. }, {
  315. desc: "integer string with trailing space",
  316. inputMessage: &pb3.Scalars{},
  317. inputText: `{"sUint32": "1e2 "}`,
  318. wantErr: true,
  319. }, {
  320. desc: "number is not an integer",
  321. inputMessage: &pb3.Scalars{},
  322. inputText: `{"sInt32": 1.001}`,
  323. wantErr: true,
  324. }, {
  325. desc: "32-bit int exceeds limit",
  326. inputMessage: &pb3.Scalars{},
  327. inputText: `{"sInt32": 2e10}`,
  328. wantErr: true,
  329. }, {
  330. desc: "64-bit int exceeds limit",
  331. inputMessage: &pb3.Scalars{},
  332. inputText: `{"sSfixed64": -9e19}`,
  333. wantErr: true,
  334. }, {
  335. desc: "not integer",
  336. inputMessage: &pb3.Scalars{},
  337. inputText: `{"sInt32": "not a number"}`,
  338. wantErr: true,
  339. }, {
  340. desc: "not unsigned integer",
  341. inputMessage: &pb3.Scalars{},
  342. inputText: `{"sUint32": "not a number"}`,
  343. wantErr: true,
  344. }, {
  345. desc: "number is not an unsigned integer",
  346. inputMessage: &pb3.Scalars{},
  347. inputText: `{"sUint32": -1}`,
  348. wantErr: true,
  349. }, {
  350. desc: "string",
  351. inputMessage: &pb2.Scalars{},
  352. inputText: `{"optString": "谷歌"}`,
  353. wantMessage: &pb2.Scalars{
  354. OptString: proto.String("谷歌"),
  355. },
  356. }, {
  357. desc: "string with invalid UTF-8",
  358. inputMessage: &pb3.Scalars{},
  359. inputText: "{\"sString\": \"\xff\"}",
  360. wantErr: true,
  361. }, {
  362. desc: "not string",
  363. inputMessage: &pb2.Scalars{},
  364. inputText: `{"optString": 42}`,
  365. wantErr: true,
  366. }, {
  367. desc: "bytes",
  368. inputMessage: &pb3.Scalars{},
  369. inputText: `{"sBytes": "aGVsbG8gd29ybGQ"}`,
  370. wantMessage: &pb3.Scalars{
  371. SBytes: []byte("hello world"),
  372. },
  373. }, {
  374. desc: "bytes padded",
  375. inputMessage: &pb3.Scalars{},
  376. inputText: `{"sBytes": "aGVsbG8gd29ybGQ="}`,
  377. wantMessage: &pb3.Scalars{
  378. SBytes: []byte("hello world"),
  379. },
  380. }, {
  381. desc: "not bytes",
  382. inputMessage: &pb3.Scalars{},
  383. inputText: `{"sBytes": true}`,
  384. wantErr: true,
  385. }, {
  386. desc: "proto2 enum",
  387. inputMessage: &pb2.Enums{},
  388. inputText: `{
  389. "optEnum": "ONE",
  390. "optNestedEnum": "UNO"
  391. }`,
  392. wantMessage: &pb2.Enums{
  393. OptEnum: pb2.Enum_ONE.Enum(),
  394. OptNestedEnum: pb2.Enums_UNO.Enum(),
  395. },
  396. }, {
  397. desc: "proto3 enum",
  398. inputMessage: &pb3.Enums{},
  399. inputText: `{
  400. "sEnum": "ONE",
  401. "sNestedEnum": "DIEZ"
  402. }`,
  403. wantMessage: &pb3.Enums{
  404. SEnum: pb3.Enum_ONE,
  405. SNestedEnum: pb3.Enums_DIEZ,
  406. },
  407. }, {
  408. desc: "enum numeric value",
  409. inputMessage: &pb3.Enums{},
  410. inputText: `{
  411. "sEnum": 2,
  412. "sNestedEnum": 2
  413. }`,
  414. wantMessage: &pb3.Enums{
  415. SEnum: pb3.Enum_TWO,
  416. SNestedEnum: pb3.Enums_DOS,
  417. },
  418. }, {
  419. desc: "enum unnamed numeric value",
  420. inputMessage: &pb3.Enums{},
  421. inputText: `{
  422. "sEnum": 101,
  423. "sNestedEnum": -101
  424. }`,
  425. wantMessage: &pb3.Enums{
  426. SEnum: 101,
  427. SNestedEnum: -101,
  428. },
  429. }, {
  430. desc: "enum set to number string",
  431. inputMessage: &pb3.Enums{},
  432. inputText: `{
  433. "sEnum": "1"
  434. }`,
  435. wantErr: true,
  436. }, {
  437. desc: "enum set to invalid named",
  438. inputMessage: &pb3.Enums{},
  439. inputText: `{
  440. "sEnum": "UNNAMED"
  441. }`,
  442. wantErr: true,
  443. }, {
  444. desc: "enum set to not enum",
  445. inputMessage: &pb3.Enums{},
  446. inputText: `{
  447. "sEnum": true
  448. }`,
  449. wantErr: true,
  450. }, {
  451. desc: "enum set to JSON null",
  452. inputMessage: &pb3.Enums{},
  453. inputText: `{
  454. "sEnum": null
  455. }`,
  456. wantMessage: &pb3.Enums{},
  457. }, {
  458. desc: "proto name",
  459. inputMessage: &pb3.JSONNames{},
  460. inputText: `{
  461. "s_string": "proto name used"
  462. }`,
  463. wantMessage: &pb3.JSONNames{
  464. SString: "proto name used",
  465. },
  466. }, {
  467. desc: "proto group name",
  468. inputMessage: &pb2.Nests{},
  469. inputText: `{
  470. "OptGroup": {"optString": "hello"},
  471. "RptGroup": [{"rptString": ["goodbye"]}]
  472. }`,
  473. wantMessage: &pb2.Nests{
  474. Optgroup: &pb2.Nests_OptGroup{OptString: proto.String("hello")},
  475. Rptgroup: []*pb2.Nests_RptGroup{{RptString: []string{"goodbye"}}},
  476. },
  477. }, {
  478. desc: "json_name",
  479. inputMessage: &pb3.JSONNames{},
  480. inputText: `{
  481. "foo_bar": "json_name used"
  482. }`,
  483. wantMessage: &pb3.JSONNames{
  484. SString: "json_name used",
  485. },
  486. }, {
  487. desc: "camelCase name",
  488. inputMessage: &pb3.JSONNames{},
  489. inputText: `{
  490. "sString": "camelcase used"
  491. }`,
  492. wantErr: true,
  493. }, {
  494. desc: "proto name and json_name",
  495. inputMessage: &pb3.JSONNames{},
  496. inputText: `{
  497. "foo_bar": "json_name used",
  498. "s_string": "proto name used"
  499. }`,
  500. wantErr: true,
  501. }, {
  502. desc: "duplicate field names",
  503. inputMessage: &pb3.JSONNames{},
  504. inputText: `{
  505. "foo_bar": "one",
  506. "foo_bar": "two",
  507. }`,
  508. wantErr: true,
  509. }, {
  510. desc: "null message",
  511. inputMessage: &pb2.Nests{},
  512. inputText: "null",
  513. wantErr: true,
  514. }, {
  515. desc: "proto2 nested message not set",
  516. inputMessage: &pb2.Nests{},
  517. inputText: "{}",
  518. wantMessage: &pb2.Nests{},
  519. }, {
  520. desc: "proto2 nested message set to null",
  521. inputMessage: &pb2.Nests{},
  522. inputText: `{
  523. "optNested": null,
  524. "optgroup": null
  525. }`,
  526. wantMessage: &pb2.Nests{},
  527. }, {
  528. desc: "proto2 nested message set to empty",
  529. inputMessage: &pb2.Nests{},
  530. inputText: `{
  531. "optNested": {},
  532. "optgroup": {}
  533. }`,
  534. wantMessage: &pb2.Nests{
  535. OptNested: &pb2.Nested{},
  536. Optgroup: &pb2.Nests_OptGroup{},
  537. },
  538. }, {
  539. desc: "proto2 nested messages",
  540. inputMessage: &pb2.Nests{},
  541. inputText: `{
  542. "optNested": {
  543. "optString": "nested message",
  544. "optNested": {
  545. "optString": "another nested message"
  546. }
  547. }
  548. }`,
  549. wantMessage: &pb2.Nests{
  550. OptNested: &pb2.Nested{
  551. OptString: proto.String("nested message"),
  552. OptNested: &pb2.Nested{
  553. OptString: proto.String("another nested message"),
  554. },
  555. },
  556. },
  557. }, {
  558. desc: "proto2 groups",
  559. inputMessage: &pb2.Nests{},
  560. inputText: `{
  561. "optgroup": {
  562. "optString": "inside a group",
  563. "optNested": {
  564. "optString": "nested message inside a group"
  565. },
  566. "optnestedgroup": {
  567. "optFixed32": 47
  568. }
  569. }
  570. }`,
  571. wantMessage: &pb2.Nests{
  572. Optgroup: &pb2.Nests_OptGroup{
  573. OptString: proto.String("inside a group"),
  574. OptNested: &pb2.Nested{
  575. OptString: proto.String("nested message inside a group"),
  576. },
  577. Optnestedgroup: &pb2.Nests_OptGroup_OptNestedGroup{
  578. OptFixed32: proto.Uint32(47),
  579. },
  580. },
  581. },
  582. }, {
  583. desc: "proto3 nested message not set",
  584. inputMessage: &pb3.Nests{},
  585. inputText: "{}",
  586. wantMessage: &pb3.Nests{},
  587. }, {
  588. desc: "proto3 nested message set to null",
  589. inputMessage: &pb3.Nests{},
  590. inputText: `{"sNested": null}`,
  591. wantMessage: &pb3.Nests{},
  592. }, {
  593. desc: "proto3 nested message set to empty",
  594. inputMessage: &pb3.Nests{},
  595. inputText: `{"sNested": {}}`,
  596. wantMessage: &pb3.Nests{
  597. SNested: &pb3.Nested{},
  598. },
  599. }, {
  600. desc: "proto3 nested message",
  601. inputMessage: &pb3.Nests{},
  602. inputText: `{
  603. "sNested": {
  604. "sString": "nested message",
  605. "sNested": {
  606. "sString": "another nested message"
  607. }
  608. }
  609. }`,
  610. wantMessage: &pb3.Nests{
  611. SNested: &pb3.Nested{
  612. SString: "nested message",
  613. SNested: &pb3.Nested{
  614. SString: "another nested message",
  615. },
  616. },
  617. },
  618. }, {
  619. desc: "message set to non-message",
  620. inputMessage: &pb3.Nests{},
  621. inputText: `"not valid"`,
  622. wantErr: true,
  623. }, {
  624. desc: "nested message set to non-message",
  625. inputMessage: &pb3.Nests{},
  626. inputText: `{"sNested": true}`,
  627. wantErr: true,
  628. }, {
  629. desc: "oneof not set",
  630. inputMessage: &pb3.Oneofs{},
  631. inputText: "{}",
  632. wantMessage: &pb3.Oneofs{},
  633. }, {
  634. desc: "oneof set to empty string",
  635. inputMessage: &pb3.Oneofs{},
  636. inputText: `{"oneofString": ""}`,
  637. wantMessage: &pb3.Oneofs{
  638. Union: &pb3.Oneofs_OneofString{},
  639. },
  640. }, {
  641. desc: "oneof set to string",
  642. inputMessage: &pb3.Oneofs{},
  643. inputText: `{"oneofString": "hello"}`,
  644. wantMessage: &pb3.Oneofs{
  645. Union: &pb3.Oneofs_OneofString{
  646. OneofString: "hello",
  647. },
  648. },
  649. }, {
  650. desc: "oneof set to enum",
  651. inputMessage: &pb3.Oneofs{},
  652. inputText: `{"oneofEnum": "ZERO"}`,
  653. wantMessage: &pb3.Oneofs{
  654. Union: &pb3.Oneofs_OneofEnum{
  655. OneofEnum: pb3.Enum_ZERO,
  656. },
  657. },
  658. }, {
  659. desc: "oneof set to empty message",
  660. inputMessage: &pb3.Oneofs{},
  661. inputText: `{"oneofNested": {}}`,
  662. wantMessage: &pb3.Oneofs{
  663. Union: &pb3.Oneofs_OneofNested{
  664. OneofNested: &pb3.Nested{},
  665. },
  666. },
  667. }, {
  668. desc: "oneof set to message",
  669. inputMessage: &pb3.Oneofs{},
  670. inputText: `{
  671. "oneofNested": {
  672. "sString": "nested message"
  673. }
  674. }`,
  675. wantMessage: &pb3.Oneofs{
  676. Union: &pb3.Oneofs_OneofNested{
  677. OneofNested: &pb3.Nested{
  678. SString: "nested message",
  679. },
  680. },
  681. },
  682. }, {
  683. desc: "oneof set to more than one field",
  684. inputMessage: &pb3.Oneofs{},
  685. inputText: `{
  686. "oneofEnum": "ZERO",
  687. "oneofString": "hello"
  688. }`,
  689. wantErr: true,
  690. }, {
  691. desc: "oneof set to null and value",
  692. inputMessage: &pb3.Oneofs{},
  693. inputText: `{
  694. "oneofEnum": "ZERO",
  695. "oneofString": null
  696. }`,
  697. wantMessage: &pb3.Oneofs{
  698. Union: &pb3.Oneofs_OneofEnum{
  699. OneofEnum: pb3.Enum_ZERO,
  700. },
  701. },
  702. }, {
  703. desc: "repeated null fields",
  704. inputMessage: &pb2.Repeats{},
  705. inputText: `{
  706. "rptString": null,
  707. "rptInt32" : null,
  708. "rptFloat" : null,
  709. "rptBytes" : null
  710. }`,
  711. wantMessage: &pb2.Repeats{},
  712. }, {
  713. desc: "repeated scalars",
  714. inputMessage: &pb2.Repeats{},
  715. inputText: `{
  716. "rptString": ["hello", "world"],
  717. "rptInt32" : [-1, 0, 1],
  718. "rptBool" : [false, true]
  719. }`,
  720. wantMessage: &pb2.Repeats{
  721. RptString: []string{"hello", "world"},
  722. RptInt32: []int32{-1, 0, 1},
  723. RptBool: []bool{false, true},
  724. },
  725. }, {
  726. desc: "repeated enums",
  727. inputMessage: &pb2.Enums{},
  728. inputText: `{
  729. "rptEnum" : ["TEN", 1, 42],
  730. "rptNestedEnum": ["DOS", 2, -47]
  731. }`,
  732. wantMessage: &pb2.Enums{
  733. RptEnum: []pb2.Enum{pb2.Enum_TEN, pb2.Enum_ONE, 42},
  734. RptNestedEnum: []pb2.Enums_NestedEnum{pb2.Enums_DOS, pb2.Enums_DOS, -47},
  735. },
  736. }, {
  737. desc: "repeated messages",
  738. inputMessage: &pb2.Nests{},
  739. inputText: `{
  740. "rptNested": [
  741. {
  742. "optString": "repeat nested one"
  743. },
  744. {
  745. "optString": "repeat nested two",
  746. "optNested": {
  747. "optString": "inside repeat nested two"
  748. }
  749. },
  750. {}
  751. ]
  752. }`,
  753. wantMessage: &pb2.Nests{
  754. RptNested: []*pb2.Nested{
  755. {
  756. OptString: proto.String("repeat nested one"),
  757. },
  758. {
  759. OptString: proto.String("repeat nested two"),
  760. OptNested: &pb2.Nested{
  761. OptString: proto.String("inside repeat nested two"),
  762. },
  763. },
  764. {},
  765. },
  766. },
  767. }, {
  768. desc: "repeated groups",
  769. inputMessage: &pb2.Nests{},
  770. inputText: `{
  771. "rptgroup": [
  772. {
  773. "rptString": ["hello", "world"]
  774. },
  775. {}
  776. ]
  777. }
  778. `,
  779. wantMessage: &pb2.Nests{
  780. Rptgroup: []*pb2.Nests_RptGroup{
  781. {
  782. RptString: []string{"hello", "world"},
  783. },
  784. {},
  785. },
  786. },
  787. }, {
  788. desc: "repeated string contains invalid UTF8",
  789. inputMessage: &pb2.Repeats{},
  790. inputText: `{"rptString": ["` + "abc\xff" + `"]}`,
  791. wantErr: true,
  792. }, {
  793. desc: "repeated messages contain invalid UTF8",
  794. inputMessage: &pb2.Nests{},
  795. inputText: `{"rptNested": [{"optString": "` + "abc\xff" + `"}]}`,
  796. wantErr: true,
  797. }, {
  798. desc: "repeated scalars contain invalid type",
  799. inputMessage: &pb2.Repeats{},
  800. inputText: `{"rptString": ["hello", null, "world"]}`,
  801. wantErr: true,
  802. }, {
  803. desc: "repeated messages contain invalid type",
  804. inputMessage: &pb2.Nests{},
  805. inputText: `{"rptNested": [{}, null]}`,
  806. wantErr: true,
  807. }, {
  808. desc: "map fields 1",
  809. inputMessage: &pb3.Maps{},
  810. inputText: `{
  811. "int32ToStr": {
  812. "-101": "-101",
  813. "0" : "zero",
  814. "255" : "0xff"
  815. },
  816. "boolToUint32": {
  817. "false": 101,
  818. "true" : "42"
  819. }
  820. }`,
  821. wantMessage: &pb3.Maps{
  822. Int32ToStr: map[int32]string{
  823. -101: "-101",
  824. 0xff: "0xff",
  825. 0: "zero",
  826. },
  827. BoolToUint32: map[bool]uint32{
  828. true: 42,
  829. false: 101,
  830. },
  831. },
  832. }, {
  833. desc: "map fields 2",
  834. inputMessage: &pb3.Maps{},
  835. inputText: `{
  836. "uint64ToEnum": {
  837. "1" : "ONE",
  838. "2" : 2,
  839. "10": 101
  840. }
  841. }`,
  842. wantMessage: &pb3.Maps{
  843. Uint64ToEnum: map[uint64]pb3.Enum{
  844. 1: pb3.Enum_ONE,
  845. 2: pb3.Enum_TWO,
  846. 10: 101,
  847. },
  848. },
  849. }, {
  850. desc: "map fields 3",
  851. inputMessage: &pb3.Maps{},
  852. inputText: `{
  853. "strToNested": {
  854. "nested_one": {
  855. "sString": "nested in a map"
  856. },
  857. "nested_two": {}
  858. }
  859. }`,
  860. wantMessage: &pb3.Maps{
  861. StrToNested: map[string]*pb3.Nested{
  862. "nested_one": {
  863. SString: "nested in a map",
  864. },
  865. "nested_two": {},
  866. },
  867. },
  868. }, {
  869. desc: "map fields 4",
  870. inputMessage: &pb3.Maps{},
  871. inputText: `{
  872. "strToOneofs": {
  873. "nested": {
  874. "oneofNested": {
  875. "sString": "nested oneof in map field value"
  876. }
  877. },
  878. "string": {
  879. "oneofString": "hello"
  880. }
  881. }
  882. }`,
  883. wantMessage: &pb3.Maps{
  884. StrToOneofs: map[string]*pb3.Oneofs{
  885. "string": {
  886. Union: &pb3.Oneofs_OneofString{
  887. OneofString: "hello",
  888. },
  889. },
  890. "nested": {
  891. Union: &pb3.Oneofs_OneofNested{
  892. OneofNested: &pb3.Nested{
  893. SString: "nested oneof in map field value",
  894. },
  895. },
  896. },
  897. },
  898. },
  899. }, {
  900. desc: "map contains duplicate keys",
  901. inputMessage: &pb3.Maps{},
  902. inputText: `{
  903. "int32ToStr": {
  904. "0": "cero",
  905. "0": "zero"
  906. }
  907. }
  908. `,
  909. wantErr: true,
  910. }, {
  911. desc: "map key empty string",
  912. inputMessage: &pb3.Maps{},
  913. inputText: `{
  914. "strToNested": {
  915. "": {}
  916. }
  917. }`,
  918. wantMessage: &pb3.Maps{
  919. StrToNested: map[string]*pb3.Nested{
  920. "": {},
  921. },
  922. },
  923. }, {
  924. desc: "map contains invalid key 1",
  925. inputMessage: &pb3.Maps{},
  926. inputText: `{
  927. "int32ToStr": {
  928. "invalid": "cero"
  929. }`,
  930. wantErr: true,
  931. }, {
  932. desc: "map contains invalid key 2",
  933. inputMessage: &pb3.Maps{},
  934. inputText: `{
  935. "int32ToStr": {
  936. "1.02": "float"
  937. }`,
  938. wantErr: true,
  939. }, {
  940. desc: "map contains invalid key 3",
  941. inputMessage: &pb3.Maps{},
  942. inputText: `{
  943. "int32ToStr": {
  944. "2147483648": "exceeds 32-bit integer max limit"
  945. }`,
  946. wantErr: true,
  947. }, {
  948. desc: "map contains invalid key 4",
  949. inputMessage: &pb3.Maps{},
  950. inputText: `{
  951. "uint64ToEnum": {
  952. "-1": 0
  953. }
  954. }`,
  955. wantErr: true,
  956. }, {
  957. desc: "map contains invalid value",
  958. inputMessage: &pb3.Maps{},
  959. inputText: `{
  960. "int32ToStr": {
  961. "101": true
  962. }`,
  963. wantErr: true,
  964. }, {
  965. desc: "map contains null for scalar value",
  966. inputMessage: &pb3.Maps{},
  967. inputText: `{
  968. "int32ToStr": {
  969. "101": null
  970. }`,
  971. wantErr: true,
  972. }, {
  973. desc: "map contains null for message value",
  974. inputMessage: &pb3.Maps{},
  975. inputText: `{
  976. "strToNested": {
  977. "hello": null
  978. }
  979. }`,
  980. wantErr: true,
  981. }, {
  982. desc: "map contains contains message value with invalid UTF8",
  983. inputMessage: &pb3.Maps{},
  984. inputText: `{
  985. "strToNested": {
  986. "hello": {
  987. "sString": "` + "abc\xff" + `"
  988. }
  989. }
  990. }`,
  991. wantErr: true,
  992. }, {
  993. desc: "map key contains invalid UTF8",
  994. inputMessage: &pb3.Maps{},
  995. inputText: `{
  996. "strToNested": {
  997. "` + "abc\xff" + `": {}
  998. }
  999. }`,
  1000. wantErr: true,
  1001. }, {
  1002. desc: "required fields not set",
  1003. inputMessage: &pb2.Requireds{},
  1004. wantErr: true,
  1005. }, {
  1006. desc: "required field set",
  1007. inputMessage: &pb2.PartialRequired{},
  1008. inputText: `{
  1009. "reqString": "this is required"
  1010. }`,
  1011. wantMessage: &pb2.PartialRequired{
  1012. ReqString: proto.String("this is required"),
  1013. },
  1014. }, {
  1015. desc: "required fields partially set",
  1016. inputMessage: &pb2.Requireds{},
  1017. inputText: `{
  1018. "reqBool": false,
  1019. "reqSfixed64": 42,
  1020. "reqString": "hello",
  1021. "reqEnum": "ONE"
  1022. }`,
  1023. wantMessage: &pb2.Requireds{
  1024. ReqBool: proto.Bool(false),
  1025. ReqSfixed64: proto.Int64(42),
  1026. ReqString: proto.String("hello"),
  1027. ReqEnum: pb2.Enum_ONE.Enum(),
  1028. },
  1029. wantErr: true,
  1030. }, {
  1031. desc: "required fields partially set with AllowPartial",
  1032. umo: protojson.UnmarshalOptions{AllowPartial: true},
  1033. inputMessage: &pb2.Requireds{},
  1034. inputText: `{
  1035. "reqBool": false,
  1036. "reqSfixed64": 42,
  1037. "reqString": "hello",
  1038. "reqEnum": "ONE"
  1039. }`,
  1040. wantMessage: &pb2.Requireds{
  1041. ReqBool: proto.Bool(false),
  1042. ReqSfixed64: proto.Int64(42),
  1043. ReqString: proto.String("hello"),
  1044. ReqEnum: pb2.Enum_ONE.Enum(),
  1045. },
  1046. }, {
  1047. desc: "required fields all set",
  1048. inputMessage: &pb2.Requireds{},
  1049. inputText: `{
  1050. "reqBool": false,
  1051. "reqSfixed64": 42,
  1052. "reqDouble": 1.23,
  1053. "reqString": "hello",
  1054. "reqEnum": "ONE",
  1055. "reqNested": {}
  1056. }`,
  1057. wantMessage: &pb2.Requireds{
  1058. ReqBool: proto.Bool(false),
  1059. ReqSfixed64: proto.Int64(42),
  1060. ReqDouble: proto.Float64(1.23),
  1061. ReqString: proto.String("hello"),
  1062. ReqEnum: pb2.Enum_ONE.Enum(),
  1063. ReqNested: &pb2.Nested{},
  1064. },
  1065. }, {
  1066. desc: "indirect required field",
  1067. inputMessage: &pb2.IndirectRequired{},
  1068. inputText: `{
  1069. "optNested": {}
  1070. }`,
  1071. wantMessage: &pb2.IndirectRequired{
  1072. OptNested: &pb2.NestedWithRequired{},
  1073. },
  1074. wantErr: true,
  1075. }, {
  1076. desc: "indirect required field with AllowPartial",
  1077. umo: protojson.UnmarshalOptions{AllowPartial: true},
  1078. inputMessage: &pb2.IndirectRequired{},
  1079. inputText: `{
  1080. "optNested": {}
  1081. }`,
  1082. wantMessage: &pb2.IndirectRequired{
  1083. OptNested: &pb2.NestedWithRequired{},
  1084. },
  1085. }, {
  1086. desc: "indirect required field in repeated",
  1087. inputMessage: &pb2.IndirectRequired{},
  1088. inputText: `{
  1089. "rptNested": [
  1090. {"reqString": "one"},
  1091. {}
  1092. ]
  1093. }`,
  1094. wantMessage: &pb2.IndirectRequired{
  1095. RptNested: []*pb2.NestedWithRequired{
  1096. {
  1097. ReqString: proto.String("one"),
  1098. },
  1099. {},
  1100. },
  1101. },
  1102. wantErr: true,
  1103. }, {
  1104. desc: "indirect required field in repeated with AllowPartial",
  1105. umo: protojson.UnmarshalOptions{AllowPartial: true},
  1106. inputMessage: &pb2.IndirectRequired{},
  1107. inputText: `{
  1108. "rptNested": [
  1109. {"reqString": "one"},
  1110. {}
  1111. ]
  1112. }`,
  1113. wantMessage: &pb2.IndirectRequired{
  1114. RptNested: []*pb2.NestedWithRequired{
  1115. {
  1116. ReqString: proto.String("one"),
  1117. },
  1118. {},
  1119. },
  1120. },
  1121. }, {
  1122. desc: "indirect required field in map",
  1123. inputMessage: &pb2.IndirectRequired{},
  1124. inputText: `{
  1125. "strToNested": {
  1126. "missing": {},
  1127. "contains": {
  1128. "reqString": "here"
  1129. }
  1130. }
  1131. }`,
  1132. wantMessage: &pb2.IndirectRequired{
  1133. StrToNested: map[string]*pb2.NestedWithRequired{
  1134. "missing": &pb2.NestedWithRequired{},
  1135. "contains": &pb2.NestedWithRequired{
  1136. ReqString: proto.String("here"),
  1137. },
  1138. },
  1139. },
  1140. wantErr: true,
  1141. }, {
  1142. desc: "indirect required field in map with AllowPartial",
  1143. umo: protojson.UnmarshalOptions{AllowPartial: true},
  1144. inputMessage: &pb2.IndirectRequired{},
  1145. inputText: `{
  1146. "strToNested": {
  1147. "missing": {},
  1148. "contains": {
  1149. "reqString": "here"
  1150. }
  1151. }
  1152. }`,
  1153. wantMessage: &pb2.IndirectRequired{
  1154. StrToNested: map[string]*pb2.NestedWithRequired{
  1155. "missing": &pb2.NestedWithRequired{},
  1156. "contains": &pb2.NestedWithRequired{
  1157. ReqString: proto.String("here"),
  1158. },
  1159. },
  1160. },
  1161. }, {
  1162. desc: "indirect required field in oneof",
  1163. inputMessage: &pb2.IndirectRequired{},
  1164. inputText: `{
  1165. "oneofNested": {}
  1166. }`,
  1167. wantMessage: &pb2.IndirectRequired{
  1168. Union: &pb2.IndirectRequired_OneofNested{
  1169. OneofNested: &pb2.NestedWithRequired{},
  1170. },
  1171. },
  1172. wantErr: true,
  1173. }, {
  1174. desc: "indirect required field in oneof with AllowPartial",
  1175. umo: protojson.UnmarshalOptions{AllowPartial: true},
  1176. inputMessage: &pb2.IndirectRequired{},
  1177. inputText: `{
  1178. "oneofNested": {}
  1179. }`,
  1180. wantMessage: &pb2.IndirectRequired{
  1181. Union: &pb2.IndirectRequired_OneofNested{
  1182. OneofNested: &pb2.NestedWithRequired{},
  1183. },
  1184. },
  1185. }, {
  1186. desc: "extensions of non-repeated fields",
  1187. inputMessage: &pb2.Extensions{},
  1188. inputText: `{
  1189. "optString": "non-extension field",
  1190. "optBool": true,
  1191. "optInt32": 42,
  1192. "[pb2.opt_ext_bool]": true,
  1193. "[pb2.opt_ext_nested]": {
  1194. "optString": "nested in an extension",
  1195. "optNested": {
  1196. "optString": "another nested in an extension"
  1197. }
  1198. },
  1199. "[pb2.opt_ext_string]": "extension field",
  1200. "[pb2.opt_ext_enum]": "TEN"
  1201. }`,
  1202. wantMessage: func() proto.Message {
  1203. m := &pb2.Extensions{
  1204. OptString: proto.String("non-extension field"),
  1205. OptBool: proto.Bool(true),
  1206. OptInt32: proto.Int32(42),
  1207. }
  1208. proto.SetExtension(m, pb2.E_OptExtBool, true)
  1209. proto.SetExtension(m, pb2.E_OptExtString, "extension field")
  1210. proto.SetExtension(m, pb2.E_OptExtEnum, pb2.Enum_TEN)
  1211. proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{
  1212. OptString: proto.String("nested in an extension"),
  1213. OptNested: &pb2.Nested{
  1214. OptString: proto.String("another nested in an extension"),
  1215. },
  1216. })
  1217. return m
  1218. }(),
  1219. }, {
  1220. desc: "extensions of repeated fields",
  1221. inputMessage: &pb2.Extensions{},
  1222. inputText: `{
  1223. "[pb2.rpt_ext_enum]": ["TEN", 101, "ONE"],
  1224. "[pb2.rpt_ext_fixed32]": [42, 47],
  1225. "[pb2.rpt_ext_nested]": [
  1226. {"optString": "one"},
  1227. {"optString": "two"},
  1228. {"optString": "three"}
  1229. ]
  1230. }`,
  1231. wantMessage: func() proto.Message {
  1232. m := &pb2.Extensions{}
  1233. proto.SetExtension(m, pb2.E_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
  1234. proto.SetExtension(m, pb2.E_RptExtFixed32, []uint32{42, 47})
  1235. proto.SetExtension(m, pb2.E_RptExtNested, []*pb2.Nested{
  1236. &pb2.Nested{OptString: proto.String("one")},
  1237. &pb2.Nested{OptString: proto.String("two")},
  1238. &pb2.Nested{OptString: proto.String("three")},
  1239. })
  1240. return m
  1241. }(),
  1242. }, {
  1243. desc: "extensions of non-repeated fields in another message",
  1244. inputMessage: &pb2.Extensions{},
  1245. inputText: `{
  1246. "[pb2.ExtensionsContainer.opt_ext_bool]": true,
  1247. "[pb2.ExtensionsContainer.opt_ext_enum]": "TEN",
  1248. "[pb2.ExtensionsContainer.opt_ext_nested]": {
  1249. "optString": "nested in an extension",
  1250. "optNested": {
  1251. "optString": "another nested in an extension"
  1252. }
  1253. },
  1254. "[pb2.ExtensionsContainer.opt_ext_string]": "extension field"
  1255. }`,
  1256. wantMessage: func() proto.Message {
  1257. m := &pb2.Extensions{}
  1258. proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtBool, true)
  1259. proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtString, "extension field")
  1260. proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtEnum, pb2.Enum_TEN)
  1261. proto.SetExtension(m, pb2.E_ExtensionsContainer_OptExtNested, &pb2.Nested{
  1262. OptString: proto.String("nested in an extension"),
  1263. OptNested: &pb2.Nested{
  1264. OptString: proto.String("another nested in an extension"),
  1265. },
  1266. })
  1267. return m
  1268. }(),
  1269. }, {
  1270. desc: "extensions of repeated fields in another message",
  1271. inputMessage: &pb2.Extensions{},
  1272. inputText: `{
  1273. "optString": "non-extension field",
  1274. "optBool": true,
  1275. "optInt32": 42,
  1276. "[pb2.ExtensionsContainer.rpt_ext_nested]": [
  1277. {"optString": "one"},
  1278. {"optString": "two"},
  1279. {"optString": "three"}
  1280. ],
  1281. "[pb2.ExtensionsContainer.rpt_ext_enum]": ["TEN", 101, "ONE"],
  1282. "[pb2.ExtensionsContainer.rpt_ext_string]": ["hello", "world"]
  1283. }`,
  1284. wantMessage: func() proto.Message {
  1285. m := &pb2.Extensions{
  1286. OptString: proto.String("non-extension field"),
  1287. OptBool: proto.Bool(true),
  1288. OptInt32: proto.Int32(42),
  1289. }
  1290. proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtEnum, []pb2.Enum{pb2.Enum_TEN, 101, pb2.Enum_ONE})
  1291. proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtString, []string{"hello", "world"})
  1292. proto.SetExtension(m, pb2.E_ExtensionsContainer_RptExtNested, []*pb2.Nested{
  1293. &pb2.Nested{OptString: proto.String("one")},
  1294. &pb2.Nested{OptString: proto.String("two")},
  1295. &pb2.Nested{OptString: proto.String("three")},
  1296. })
  1297. return m
  1298. }(),
  1299. }, {
  1300. desc: "invalid extension field name",
  1301. inputMessage: &pb2.Extensions{},
  1302. inputText: `{ "[pb2.invalid_message_field]": true }`,
  1303. wantErr: true,
  1304. }, {
  1305. desc: "extensions of repeated field contains null",
  1306. inputMessage: &pb2.Extensions{},
  1307. inputText: `{
  1308. "[pb2.ExtensionsContainer.rpt_ext_nested]": [
  1309. {"optString": "one"},
  1310. null,
  1311. {"optString": "three"}
  1312. ],
  1313. }`,
  1314. wantErr: true,
  1315. }, {
  1316. desc: "MessageSet",
  1317. inputMessage: &pb2.MessageSet{},
  1318. inputText: `{
  1319. "[pb2.MessageSetExtension]": {
  1320. "optString": "a messageset extension"
  1321. },
  1322. "[pb2.MessageSetExtension.ext_nested]": {
  1323. "optString": "just a regular extension"
  1324. },
  1325. "[pb2.MessageSetExtension.not_message_set_extension]": {
  1326. "optString": "not a messageset extension"
  1327. }
  1328. }`,
  1329. wantMessage: func() proto.Message {
  1330. m := &pb2.MessageSet{}
  1331. proto.SetExtension(m, pb2.E_MessageSetExtension_MessageSetExtension, &pb2.MessageSetExtension{
  1332. OptString: proto.String("a messageset extension"),
  1333. })
  1334. proto.SetExtension(m, pb2.E_MessageSetExtension_NotMessageSetExtension, &pb2.MessageSetExtension{
  1335. OptString: proto.String("not a messageset extension"),
  1336. })
  1337. proto.SetExtension(m, pb2.E_MessageSetExtension_ExtNested, &pb2.Nested{
  1338. OptString: proto.String("just a regular extension"),
  1339. })
  1340. return m
  1341. }(),
  1342. skip: !flags.ProtoLegacy,
  1343. }, {
  1344. desc: "not real MessageSet 1",
  1345. inputMessage: &pb2.FakeMessageSet{},
  1346. inputText: `{
  1347. "[pb2.FakeMessageSetExtension.message_set_extension]": {
  1348. "optString": "not a messageset extension"
  1349. }
  1350. }`,
  1351. wantMessage: func() proto.Message {
  1352. m := &pb2.FakeMessageSet{}
  1353. proto.SetExtension(m, pb2.E_FakeMessageSetExtension_MessageSetExtension, &pb2.FakeMessageSetExtension{
  1354. OptString: proto.String("not a messageset extension"),
  1355. })
  1356. return m
  1357. }(),
  1358. skip: !flags.ProtoLegacy,
  1359. }, {
  1360. desc: "not real MessageSet 2",
  1361. inputMessage: &pb2.FakeMessageSet{},
  1362. inputText: `{
  1363. "[pb2.FakeMessageSetExtension]": {
  1364. "optString": "not a messageset extension"
  1365. }
  1366. }`,
  1367. wantErr: true,
  1368. skip: !flags.ProtoLegacy,
  1369. }, {
  1370. desc: "not real MessageSet 3",
  1371. inputMessage: &pb2.MessageSet{},
  1372. inputText: `{
  1373. "[pb2.message_set_extension]": {
  1374. "optString": "another not a messageset extension"
  1375. }
  1376. }`,
  1377. wantMessage: func() proto.Message {
  1378. m := &pb2.MessageSet{}
  1379. proto.SetExtension(m, pb2.E_MessageSetExtension, &pb2.FakeMessageSetExtension{
  1380. OptString: proto.String("another not a messageset extension"),
  1381. })
  1382. return m
  1383. }(),
  1384. skip: !flags.ProtoLegacy,
  1385. }, {
  1386. desc: "Empty",
  1387. inputMessage: &emptypb.Empty{},
  1388. inputText: `{}`,
  1389. wantMessage: &emptypb.Empty{},
  1390. }, {
  1391. desc: "Empty contains unknown",
  1392. inputMessage: &emptypb.Empty{},
  1393. inputText: `{"unknown": null}`,
  1394. wantErr: true,
  1395. }, {
  1396. desc: "BoolValue false",
  1397. inputMessage: &wrapperspb.BoolValue{},
  1398. inputText: `false`,
  1399. wantMessage: &wrapperspb.BoolValue{},
  1400. }, {
  1401. desc: "BoolValue true",
  1402. inputMessage: &wrapperspb.BoolValue{},
  1403. inputText: `true`,
  1404. wantMessage: &wrapperspb.BoolValue{Value: true},
  1405. }, {
  1406. desc: "BoolValue invalid value",
  1407. inputMessage: &wrapperspb.BoolValue{},
  1408. inputText: `{}`,
  1409. wantErr: true,
  1410. }, {
  1411. desc: "Int32Value",
  1412. inputMessage: &wrapperspb.Int32Value{},
  1413. inputText: `42`,
  1414. wantMessage: &wrapperspb.Int32Value{Value: 42},
  1415. }, {
  1416. desc: "Int32Value in JSON string",
  1417. inputMessage: &wrapperspb.Int32Value{},
  1418. inputText: `"1.23e3"`,
  1419. wantMessage: &wrapperspb.Int32Value{Value: 1230},
  1420. }, {
  1421. desc: "Int64Value",
  1422. inputMessage: &wrapperspb.Int64Value{},
  1423. inputText: `"42"`,
  1424. wantMessage: &wrapperspb.Int64Value{Value: 42},
  1425. }, {
  1426. desc: "UInt32Value",
  1427. inputMessage: &wrapperspb.UInt32Value{},
  1428. inputText: `42`,
  1429. wantMessage: &wrapperspb.UInt32Value{Value: 42},
  1430. }, {
  1431. desc: "UInt64Value",
  1432. inputMessage: &wrapperspb.UInt64Value{},
  1433. inputText: `"42"`,
  1434. wantMessage: &wrapperspb.UInt64Value{Value: 42},
  1435. }, {
  1436. desc: "FloatValue",
  1437. inputMessage: &wrapperspb.FloatValue{},
  1438. inputText: `1.02`,
  1439. wantMessage: &wrapperspb.FloatValue{Value: 1.02},
  1440. }, {
  1441. desc: "FloatValue exceeds max limit",
  1442. inputMessage: &wrapperspb.FloatValue{},
  1443. inputText: `1.23+40`,
  1444. wantErr: true,
  1445. }, {
  1446. desc: "FloatValue Infinity",
  1447. inputMessage: &wrapperspb.FloatValue{},
  1448. inputText: `"-Infinity"`,
  1449. wantMessage: &wrapperspb.FloatValue{Value: float32(math.Inf(-1))},
  1450. }, {
  1451. desc: "DoubleValue",
  1452. inputMessage: &wrapperspb.DoubleValue{},
  1453. inputText: `1.02`,
  1454. wantMessage: &wrapperspb.DoubleValue{Value: 1.02},
  1455. }, {
  1456. desc: "DoubleValue Infinity",
  1457. inputMessage: &wrapperspb.DoubleValue{},
  1458. inputText: `"Infinity"`,
  1459. wantMessage: &wrapperspb.DoubleValue{Value: math.Inf(+1)},
  1460. }, {
  1461. desc: "StringValue empty",
  1462. inputMessage: &wrapperspb.StringValue{},
  1463. inputText: `""`,
  1464. wantMessage: &wrapperspb.StringValue{},
  1465. }, {
  1466. desc: "StringValue",
  1467. inputMessage: &wrapperspb.StringValue{},
  1468. inputText: `"谷歌"`,
  1469. wantMessage: &wrapperspb.StringValue{Value: "谷歌"},
  1470. }, {
  1471. desc: "StringValue with invalid UTF8 error",
  1472. inputMessage: &wrapperspb.StringValue{},
  1473. inputText: "\"abc\xff\"",
  1474. wantErr: true,
  1475. }, {
  1476. desc: "StringValue field with invalid UTF8 error",
  1477. inputMessage: &pb2.KnownTypes{},
  1478. inputText: "{\n \"optString\": \"abc\xff\"\n}",
  1479. wantErr: true,
  1480. }, {
  1481. desc: "NullValue field with JSON null",
  1482. inputMessage: &pb2.KnownTypes{},
  1483. inputText: `{
  1484. "optNull": null
  1485. }`,
  1486. wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
  1487. }, {
  1488. desc: "NullValue field with string",
  1489. inputMessage: &pb2.KnownTypes{},
  1490. inputText: `{
  1491. "optNull": "NULL_VALUE"
  1492. }`,
  1493. wantMessage: &pb2.KnownTypes{OptNull: new(structpb.NullValue)},
  1494. }, {
  1495. desc: "BytesValue",
  1496. inputMessage: &wrapperspb.BytesValue{},
  1497. inputText: `"aGVsbG8="`,
  1498. wantMessage: &wrapperspb.BytesValue{Value: []byte("hello")},
  1499. }, {
  1500. desc: "Value null",
  1501. inputMessage: &structpb.Value{},
  1502. inputText: `null`,
  1503. wantMessage: &structpb.Value{Kind: &structpb.Value_NullValue{}},
  1504. }, {
  1505. desc: "Value field null",
  1506. inputMessage: &pb2.KnownTypes{},
  1507. inputText: `{
  1508. "optValue": null
  1509. }`,
  1510. wantMessage: &pb2.KnownTypes{
  1511. OptValue: &structpb.Value{Kind: &structpb.Value_NullValue{}},
  1512. },
  1513. }, {
  1514. desc: "Value bool",
  1515. inputMessage: &structpb.Value{},
  1516. inputText: `false`,
  1517. wantMessage: &structpb.Value{Kind: &structpb.Value_BoolValue{}},
  1518. }, {
  1519. desc: "Value field bool",
  1520. inputMessage: &pb2.KnownTypes{},
  1521. inputText: `{
  1522. "optValue": true
  1523. }`,
  1524. wantMessage: &pb2.KnownTypes{
  1525. OptValue: &structpb.Value{Kind: &structpb.Value_BoolValue{true}},
  1526. },
  1527. }, {
  1528. desc: "Value number",
  1529. inputMessage: &structpb.Value{},
  1530. inputText: `1.02`,
  1531. wantMessage: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
  1532. }, {
  1533. desc: "Value field number",
  1534. inputMessage: &pb2.KnownTypes{},
  1535. inputText: `{
  1536. "optValue": 1.02
  1537. }`,
  1538. wantMessage: &pb2.KnownTypes{
  1539. OptValue: &structpb.Value{Kind: &structpb.Value_NumberValue{1.02}},
  1540. },
  1541. }, {
  1542. desc: "Value string",
  1543. inputMessage: &structpb.Value{},
  1544. inputText: `"hello"`,
  1545. wantMessage: &structpb.Value{Kind: &structpb.Value_StringValue{"hello"}},
  1546. }, {
  1547. desc: "Value string with invalid UTF8",
  1548. inputMessage: &structpb.Value{},
  1549. inputText: "\"\xff\"",
  1550. wantErr: true,
  1551. }, {
  1552. desc: "Value field string",
  1553. inputMessage: &pb2.KnownTypes{},
  1554. inputText: `{
  1555. "optValue": "NaN"
  1556. }`,
  1557. wantMessage: &pb2.KnownTypes{
  1558. OptValue: &structpb.Value{Kind: &structpb.Value_StringValue{"NaN"}},
  1559. },
  1560. }, {
  1561. desc: "Value field string with invalid UTF8",
  1562. inputMessage: &pb2.KnownTypes{},
  1563. inputText: `{
  1564. "optValue": "` + "\xff" + `"
  1565. }`,
  1566. wantErr: true,
  1567. }, {
  1568. desc: "Value empty struct",
  1569. inputMessage: &structpb.Value{},
  1570. inputText: `{}`,
  1571. wantMessage: &structpb.Value{
  1572. Kind: &structpb.Value_StructValue{
  1573. &structpb.Struct{Fields: map[string]*structpb.Value{}},
  1574. },
  1575. },
  1576. }, {
  1577. desc: "Value struct",
  1578. inputMessage: &structpb.Value{},
  1579. inputText: `{
  1580. "string": "hello",
  1581. "number": 123,
  1582. "null": null,
  1583. "bool": false,
  1584. "struct": {
  1585. "string": "world"
  1586. },
  1587. "list": []
  1588. }`,
  1589. wantMessage: &structpb.Value{
  1590. Kind: &structpb.Value_StructValue{
  1591. &structpb.Struct{
  1592. Fields: map[string]*structpb.Value{
  1593. "string": {Kind: &structpb.Value_StringValue{"hello"}},
  1594. "number": {Kind: &structpb.Value_NumberValue{123}},
  1595. "null": {Kind: &structpb.Value_NullValue{}},
  1596. "bool": {Kind: &structpb.Value_BoolValue{false}},
  1597. "struct": {
  1598. Kind: &structpb.Value_StructValue{
  1599. &structpb.Struct{
  1600. Fields: map[string]*structpb.Value{
  1601. "string": {Kind: &structpb.Value_StringValue{"world"}},
  1602. },
  1603. },
  1604. },
  1605. },
  1606. "list": {
  1607. Kind: &structpb.Value_ListValue{&structpb.ListValue{}},
  1608. },
  1609. },
  1610. },
  1611. },
  1612. },
  1613. }, {
  1614. desc: "Value struct with invalid UTF8 string",
  1615. inputMessage: &structpb.Value{},
  1616. inputText: "{\"string\": \"abc\xff\"}",
  1617. wantErr: true,
  1618. }, {
  1619. desc: "Value field struct",
  1620. inputMessage: &pb2.KnownTypes{},
  1621. inputText: `{
  1622. "optValue": {
  1623. "string": "hello"
  1624. }
  1625. }`,
  1626. wantMessage: &pb2.KnownTypes{
  1627. OptValue: &structpb.Value{
  1628. Kind: &structpb.Value_StructValue{
  1629. &structpb.Struct{
  1630. Fields: map[string]*structpb.Value{
  1631. "string": {Kind: &structpb.Value_StringValue{"hello"}},
  1632. },
  1633. },
  1634. },
  1635. },
  1636. },
  1637. }, {
  1638. desc: "Value empty list",
  1639. inputMessage: &structpb.Value{},
  1640. inputText: `[]`,
  1641. wantMessage: &structpb.Value{
  1642. Kind: &structpb.Value_ListValue{
  1643. &structpb.ListValue{Values: []*structpb.Value{}},
  1644. },
  1645. },
  1646. }, {
  1647. desc: "Value list",
  1648. inputMessage: &structpb.Value{},
  1649. inputText: `[
  1650. "string",
  1651. 123,
  1652. null,
  1653. true,
  1654. {},
  1655. [
  1656. "string",
  1657. 1.23,
  1658. null,
  1659. false
  1660. ]
  1661. ]`,
  1662. wantMessage: &structpb.Value{
  1663. Kind: &structpb.Value_ListValue{
  1664. &structpb.ListValue{
  1665. Values: []*structpb.Value{
  1666. {Kind: &structpb.Value_StringValue{"string"}},
  1667. {Kind: &structpb.Value_NumberValue{123}},
  1668. {Kind: &structpb.Value_NullValue{}},
  1669. {Kind: &structpb.Value_BoolValue{true}},
  1670. {Kind: &structpb.Value_StructValue{&structpb.Struct{}}},
  1671. {
  1672. Kind: &structpb.Value_ListValue{
  1673. &structpb.ListValue{
  1674. Values: []*structpb.Value{
  1675. {Kind: &structpb.Value_StringValue{"string"}},
  1676. {Kind: &structpb.Value_NumberValue{1.23}},
  1677. {Kind: &structpb.Value_NullValue{}},
  1678. {Kind: &structpb.Value_BoolValue{false}},
  1679. },
  1680. },
  1681. },
  1682. },
  1683. },
  1684. },
  1685. },
  1686. },
  1687. }, {
  1688. desc: "Value list with invalid UTF8 string",
  1689. inputMessage: &structpb.Value{},
  1690. inputText: "[\"abc\xff\"]",
  1691. wantErr: true,
  1692. }, {
  1693. desc: "Value field list with invalid UTF8 string",
  1694. inputMessage: &pb2.KnownTypes{},
  1695. inputText: `{
  1696. "optValue": [ "` + "abc\xff" + `"]
  1697. }`,
  1698. wantErr: true,
  1699. }, {
  1700. desc: "Duration empty string",
  1701. inputMessage: &durationpb.Duration{},
  1702. inputText: `""`,
  1703. wantErr: true,
  1704. }, {
  1705. desc: "Duration with secs",
  1706. inputMessage: &durationpb.Duration{},
  1707. inputText: `"3s"`,
  1708. wantMessage: &durationpb.Duration{Seconds: 3},
  1709. }, {
  1710. desc: "Duration with escaped unicode",
  1711. inputMessage: &durationpb.Duration{},
  1712. inputText: `"\u0033s"`,
  1713. wantMessage: &durationpb.Duration{Seconds: 3},
  1714. }, {
  1715. desc: "Duration with -secs",
  1716. inputMessage: &durationpb.Duration{},
  1717. inputText: `"-3s"`,
  1718. wantMessage: &durationpb.Duration{Seconds: -3},
  1719. }, {
  1720. desc: "Duration with plus sign",
  1721. inputMessage: &durationpb.Duration{},
  1722. inputText: `"+3s"`,
  1723. wantMessage: &durationpb.Duration{Seconds: 3},
  1724. }, {
  1725. desc: "Duration with nanos",
  1726. inputMessage: &durationpb.Duration{},
  1727. inputText: `"0.001s"`,
  1728. wantMessage: &durationpb.Duration{Nanos: 1e6},
  1729. }, {
  1730. desc: "Duration with -nanos",
  1731. inputMessage: &durationpb.Duration{},
  1732. inputText: `"-0.001s"`,
  1733. wantMessage: &durationpb.Duration{Nanos: -1e6},
  1734. }, {
  1735. desc: "Duration with -nanos",
  1736. inputMessage: &durationpb.Duration{},
  1737. inputText: `"-.001s"`,
  1738. wantMessage: &durationpb.Duration{Nanos: -1e6},
  1739. }, {
  1740. desc: "Duration with +nanos",
  1741. inputMessage: &durationpb.Duration{},
  1742. inputText: `"+.001s"`,
  1743. wantMessage: &durationpb.Duration{Nanos: 1e6},
  1744. }, {
  1745. desc: "Duration with -secs -nanos",
  1746. inputMessage: &durationpb.Duration{},
  1747. inputText: `"-123.000000450s"`,
  1748. wantMessage: &durationpb.Duration{Seconds: -123, Nanos: -450},
  1749. }, {
  1750. desc: "Duration with large secs",
  1751. inputMessage: &durationpb.Duration{},
  1752. inputText: `"10000000000.000000001s"`,
  1753. wantMessage: &durationpb.Duration{Seconds: 1e10, Nanos: 1},
  1754. }, {
  1755. desc: "Duration with decimal without fractional",
  1756. inputMessage: &durationpb.Duration{},
  1757. inputText: `"3.s"`,
  1758. wantMessage: &durationpb.Duration{Seconds: 3},
  1759. }, {
  1760. desc: "Duration with decimal without integer",
  1761. inputMessage: &durationpb.Duration{},
  1762. inputText: `"0.5s"`,
  1763. wantMessage: &durationpb.Duration{Nanos: 5e8},
  1764. }, {
  1765. desc: "Duration max value",
  1766. inputMessage: &durationpb.Duration{},
  1767. inputText: `"315576000000.999999999s"`,
  1768. wantMessage: &durationpb.Duration{Seconds: 315576000000, Nanos: 999999999},
  1769. }, {
  1770. desc: "Duration min value",
  1771. inputMessage: &durationpb.Duration{},
  1772. inputText: `"-315576000000.999999999s"`,
  1773. wantMessage: &durationpb.Duration{Seconds: -315576000000, Nanos: -999999999},
  1774. }, {
  1775. desc: "Duration with +secs out of range",
  1776. inputMessage: &durationpb.Duration{},
  1777. inputText: `"315576000001s"`,
  1778. wantErr: true,
  1779. }, {
  1780. desc: "Duration with -secs out of range",
  1781. inputMessage: &durationpb.Duration{},
  1782. inputText: `"-315576000001s"`,
  1783. wantErr: true,
  1784. }, {
  1785. desc: "Duration with nanos beyond 9 digits",
  1786. inputMessage: &durationpb.Duration{},
  1787. inputText: `"0.1000000000s"`,
  1788. wantErr: true,
  1789. }, {
  1790. desc: "Duration without suffix s",
  1791. inputMessage: &durationpb.Duration{},
  1792. inputText: `"123"`,
  1793. wantErr: true,
  1794. }, {
  1795. desc: "Duration invalid signed fraction",
  1796. inputMessage: &durationpb.Duration{},
  1797. inputText: `"123.+123s"`,
  1798. wantErr: true,
  1799. }, {
  1800. desc: "Duration invalid multiple .",
  1801. inputMessage: &durationpb.Duration{},
  1802. inputText: `"123.123.s"`,
  1803. wantErr: true,
  1804. }, {
  1805. desc: "Duration invalid integer",
  1806. inputMessage: &durationpb.Duration{},
  1807. inputText: `"01s"`,
  1808. wantErr: true,
  1809. }, {
  1810. desc: "Timestamp zero",
  1811. inputMessage: &timestamppb.Timestamp{},
  1812. inputText: `"1970-01-01T00:00:00Z"`,
  1813. wantMessage: &timestamppb.Timestamp{},
  1814. }, {
  1815. desc: "Timestamp with tz adjustment",
  1816. inputMessage: &timestamppb.Timestamp{},
  1817. inputText: `"1970-01-01T00:00:00+01:00"`,
  1818. wantMessage: &timestamppb.Timestamp{Seconds: -3600},
  1819. }, {
  1820. desc: "Timestamp UTC",
  1821. inputMessage: &timestamppb.Timestamp{},
  1822. inputText: `"2019-03-19T23:03:21Z"`,
  1823. wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
  1824. }, {
  1825. desc: "Timestamp with escaped unicode",
  1826. inputMessage: &timestamppb.Timestamp{},
  1827. inputText: `"2019-0\u0033-19T23:03:21Z"`,
  1828. wantMessage: &timestamppb.Timestamp{Seconds: 1553036601},
  1829. }, {
  1830. desc: "Timestamp with nanos",
  1831. inputMessage: &timestamppb.Timestamp{},
  1832. inputText: `"2019-03-19T23:03:21.000000001Z"`,
  1833. wantMessage: &timestamppb.Timestamp{Seconds: 1553036601, Nanos: 1},
  1834. }, {
  1835. desc: "Timestamp max value",
  1836. inputMessage: &timestamppb.Timestamp{},
  1837. inputText: `"9999-12-31T23:59:59.999999999Z"`,
  1838. wantMessage: &timestamppb.Timestamp{Seconds: 253402300799, Nanos: 999999999},
  1839. }, {
  1840. desc: "Timestamp above max value",
  1841. inputMessage: &timestamppb.Timestamp{},
  1842. inputText: `"9999-12-31T23:59:59-01:00"`,
  1843. wantErr: true,
  1844. }, {
  1845. desc: "Timestamp min value",
  1846. inputMessage: &timestamppb.Timestamp{},
  1847. inputText: `"0001-01-01T00:00:00Z"`,
  1848. wantMessage: &timestamppb.Timestamp{Seconds: -62135596800},
  1849. }, {
  1850. desc: "Timestamp below min value",
  1851. inputMessage: &timestamppb.Timestamp{},
  1852. inputText: `"0001-01-01T00:00:00+01:00"`,
  1853. wantErr: true,
  1854. }, {
  1855. desc: "Timestamp with nanos beyond 9 digits",
  1856. inputMessage: &timestamppb.Timestamp{},
  1857. inputText: `"1970-01-01T00:00:00.0000000001Z"`,
  1858. wantErr: true,
  1859. }, {
  1860. desc: "FieldMask empty",
  1861. inputMessage: &fieldmaskpb.FieldMask{},
  1862. inputText: `""`,
  1863. wantMessage: &fieldmaskpb.FieldMask{Paths: []string{}},
  1864. }, {
  1865. desc: "FieldMask",
  1866. inputMessage: &fieldmaskpb.FieldMask{},
  1867. inputText: `"foo,fooBar , foo.barQux ,Foo"`,
  1868. wantMessage: &fieldmaskpb.FieldMask{
  1869. Paths: []string{
  1870. "foo",
  1871. "foo_bar",
  1872. "foo.bar_qux",
  1873. "_foo",
  1874. },
  1875. },
  1876. }, {
  1877. desc: "FieldMask field",
  1878. inputMessage: &pb2.KnownTypes{},
  1879. inputText: `{
  1880. "optFieldmask": "foo, qux.fooBar"
  1881. }`,
  1882. wantMessage: &pb2.KnownTypes{
  1883. OptFieldmask: &fieldmaskpb.FieldMask{
  1884. Paths: []string{
  1885. "foo",
  1886. "qux.foo_bar",
  1887. },
  1888. },
  1889. },
  1890. }, {
  1891. desc: "Any empty",
  1892. inputMessage: &anypb.Any{},
  1893. inputText: `{}`,
  1894. wantMessage: &anypb.Any{},
  1895. }, {
  1896. desc: "Any with non-custom message",
  1897. inputMessage: &anypb.Any{},
  1898. inputText: `{
  1899. "@type": "foo/pb2.Nested",
  1900. "optString": "embedded inside Any",
  1901. "optNested": {
  1902. "optString": "inception"
  1903. }
  1904. }`,
  1905. wantMessage: func() proto.Message {
  1906. m := &pb2.Nested{
  1907. OptString: proto.String("embedded inside Any"),
  1908. OptNested: &pb2.Nested{
  1909. OptString: proto.String("inception"),
  1910. },
  1911. }
  1912. b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
  1913. if err != nil {
  1914. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  1915. }
  1916. return &anypb.Any{
  1917. TypeUrl: "foo/pb2.Nested",
  1918. Value: b,
  1919. }
  1920. }(),
  1921. }, {
  1922. desc: "Any with empty embedded message",
  1923. inputMessage: &anypb.Any{},
  1924. inputText: `{"@type": "foo/pb2.Nested"}`,
  1925. wantMessage: &anypb.Any{TypeUrl: "foo/pb2.Nested"},
  1926. }, {
  1927. desc: "Any without registered type",
  1928. umo: protojson.UnmarshalOptions{Resolver: new(preg.Types)},
  1929. inputMessage: &anypb.Any{},
  1930. inputText: `{"@type": "foo/pb2.Nested"}`,
  1931. wantErr: true,
  1932. }, {
  1933. desc: "Any with missing required",
  1934. inputMessage: &anypb.Any{},
  1935. inputText: `{
  1936. "@type": "pb2.PartialRequired",
  1937. "optString": "embedded inside Any"
  1938. }`,
  1939. wantMessage: func() proto.Message {
  1940. m := &pb2.PartialRequired{
  1941. OptString: proto.String("embedded inside Any"),
  1942. }
  1943. b, err := proto.MarshalOptions{
  1944. Deterministic: true,
  1945. AllowPartial: true,
  1946. }.Marshal(m)
  1947. if err != nil {
  1948. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  1949. }
  1950. return &anypb.Any{
  1951. TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
  1952. Value: b,
  1953. }
  1954. }(),
  1955. }, {
  1956. desc: "Any with partial required and AllowPartial",
  1957. umo: protojson.UnmarshalOptions{
  1958. AllowPartial: true,
  1959. },
  1960. inputMessage: &anypb.Any{},
  1961. inputText: `{
  1962. "@type": "pb2.PartialRequired",
  1963. "optString": "embedded inside Any"
  1964. }`,
  1965. wantMessage: func() proto.Message {
  1966. m := &pb2.PartialRequired{
  1967. OptString: proto.String("embedded inside Any"),
  1968. }
  1969. b, err := proto.MarshalOptions{
  1970. Deterministic: true,
  1971. AllowPartial: true,
  1972. }.Marshal(m)
  1973. if err != nil {
  1974. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  1975. }
  1976. return &anypb.Any{
  1977. TypeUrl: string(m.ProtoReflect().Descriptor().FullName()),
  1978. Value: b,
  1979. }
  1980. }(),
  1981. }, {
  1982. desc: "Any with invalid UTF8",
  1983. inputMessage: &anypb.Any{},
  1984. inputText: `{
  1985. "optString": "` + "abc\xff" + `",
  1986. "@type": "foo/pb2.Nested"
  1987. }`,
  1988. wantErr: true,
  1989. }, {
  1990. desc: "Any with BoolValue",
  1991. inputMessage: &anypb.Any{},
  1992. inputText: `{
  1993. "@type": "type.googleapis.com/google.protobuf.BoolValue",
  1994. "value": true
  1995. }`,
  1996. wantMessage: func() proto.Message {
  1997. m := &wrapperspb.BoolValue{Value: true}
  1998. b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
  1999. if err != nil {
  2000. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  2001. }
  2002. return &anypb.Any{
  2003. TypeUrl: "type.googleapis.com/google.protobuf.BoolValue",
  2004. Value: b,
  2005. }
  2006. }(),
  2007. }, {
  2008. desc: "Any with Empty",
  2009. inputMessage: &anypb.Any{},
  2010. inputText: `{
  2011. "value": {},
  2012. "@type": "type.googleapis.com/google.protobuf.Empty"
  2013. }`,
  2014. wantMessage: &anypb.Any{
  2015. TypeUrl: "type.googleapis.com/google.protobuf.Empty",
  2016. },
  2017. }, {
  2018. desc: "Any with missing Empty",
  2019. inputMessage: &anypb.Any{},
  2020. inputText: `{
  2021. "@type": "type.googleapis.com/google.protobuf.Empty"
  2022. }`,
  2023. wantErr: true,
  2024. }, {
  2025. desc: "Any with StringValue containing invalid UTF8",
  2026. inputMessage: &anypb.Any{},
  2027. inputText: `{
  2028. "@type": "google.protobuf.StringValue",
  2029. "value": "` + "abc\xff" + `"
  2030. }`,
  2031. wantErr: true,
  2032. }, {
  2033. desc: "Any with Int64Value",
  2034. inputMessage: &anypb.Any{},
  2035. inputText: `{
  2036. "@type": "google.protobuf.Int64Value",
  2037. "value": "42"
  2038. }`,
  2039. wantMessage: func() proto.Message {
  2040. m := &wrapperspb.Int64Value{Value: 42}
  2041. b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
  2042. if err != nil {
  2043. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  2044. }
  2045. return &anypb.Any{
  2046. TypeUrl: "google.protobuf.Int64Value",
  2047. Value: b,
  2048. }
  2049. }(),
  2050. }, {
  2051. desc: "Any with invalid Int64Value",
  2052. inputMessage: &anypb.Any{},
  2053. inputText: `{
  2054. "@type": "google.protobuf.Int64Value",
  2055. "value": "forty-two"
  2056. }`,
  2057. wantErr: true,
  2058. }, {
  2059. desc: "Any with invalid UInt64Value",
  2060. inputMessage: &anypb.Any{},
  2061. inputText: `{
  2062. "@type": "google.protobuf.UInt64Value",
  2063. "value": -42
  2064. }`,
  2065. wantErr: true,
  2066. }, {
  2067. desc: "Any with Duration",
  2068. inputMessage: &anypb.Any{},
  2069. inputText: `{
  2070. "@type": "type.googleapis.com/google.protobuf.Duration",
  2071. "value": "0s"
  2072. }`,
  2073. wantMessage: func() proto.Message {
  2074. m := &durationpb.Duration{}
  2075. b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
  2076. if err != nil {
  2077. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  2078. }
  2079. return &anypb.Any{
  2080. TypeUrl: "type.googleapis.com/google.protobuf.Duration",
  2081. Value: b,
  2082. }
  2083. }(),
  2084. }, {
  2085. desc: "Any with Value of StringValue",
  2086. inputMessage: &anypb.Any{},
  2087. inputText: `{
  2088. "@type": "google.protobuf.Value",
  2089. "value": "` + "abc\xff" + `"
  2090. }`,
  2091. wantErr: true,
  2092. }, {
  2093. desc: "Any with Value of NullValue",
  2094. inputMessage: &anypb.Any{},
  2095. inputText: `{
  2096. "@type": "google.protobuf.Value",
  2097. "value": null
  2098. }`,
  2099. wantMessage: func() proto.Message {
  2100. m := &structpb.Value{Kind: &structpb.Value_NullValue{}}
  2101. b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
  2102. if err != nil {
  2103. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  2104. }
  2105. return &anypb.Any{
  2106. TypeUrl: "google.protobuf.Value",
  2107. Value: b,
  2108. }
  2109. }(),
  2110. }, {
  2111. desc: "Any with Struct",
  2112. inputMessage: &anypb.Any{},
  2113. inputText: `{
  2114. "@type": "google.protobuf.Struct",
  2115. "value": {
  2116. "bool": true,
  2117. "null": null,
  2118. "string": "hello",
  2119. "struct": {
  2120. "string": "world"
  2121. }
  2122. }
  2123. }`,
  2124. wantMessage: func() proto.Message {
  2125. m := &structpb.Struct{
  2126. Fields: map[string]*structpb.Value{
  2127. "bool": {Kind: &structpb.Value_BoolValue{true}},
  2128. "null": {Kind: &structpb.Value_NullValue{}},
  2129. "string": {Kind: &structpb.Value_StringValue{"hello"}},
  2130. "struct": {
  2131. Kind: &structpb.Value_StructValue{
  2132. &structpb.Struct{
  2133. Fields: map[string]*structpb.Value{
  2134. "string": {Kind: &structpb.Value_StringValue{"world"}},
  2135. },
  2136. },
  2137. },
  2138. },
  2139. },
  2140. }
  2141. b, err := proto.MarshalOptions{Deterministic: true}.Marshal(m)
  2142. if err != nil {
  2143. t.Fatalf("error in binary marshaling message for Any.value: %v", err)
  2144. }
  2145. return &anypb.Any{
  2146. TypeUrl: "google.protobuf.Struct",
  2147. Value: b,
  2148. }
  2149. }(),
  2150. }, {
  2151. desc: "Any with missing @type",
  2152. umo: protojson.UnmarshalOptions{},
  2153. inputMessage: &anypb.Any{},
  2154. inputText: `{
  2155. "value": {}
  2156. }`,
  2157. wantErr: true,
  2158. }, {
  2159. desc: "Any with empty @type",
  2160. inputMessage: &anypb.Any{},
  2161. inputText: `{
  2162. "@type": ""
  2163. }`,
  2164. wantErr: true,
  2165. }, {
  2166. desc: "Any with duplicate @type",
  2167. inputMessage: &anypb.Any{},
  2168. inputText: `{
  2169. "@type": "google.protobuf.StringValue",
  2170. "value": "hello",
  2171. "@type": "pb2.Nested"
  2172. }`,
  2173. wantErr: true,
  2174. }, {
  2175. desc: "Any with duplicate value",
  2176. inputMessage: &anypb.Any{},
  2177. inputText: `{
  2178. "@type": "google.protobuf.StringValue",
  2179. "value": "hello",
  2180. "value": "world"
  2181. }`,
  2182. wantErr: true,
  2183. }, {
  2184. desc: "Any with unknown field",
  2185. inputMessage: &anypb.Any{},
  2186. inputText: `{
  2187. "@type": "pb2.Nested",
  2188. "optString": "hello",
  2189. "unknown": "world"
  2190. }`,
  2191. wantErr: true,
  2192. }, {
  2193. desc: "Any with embedded type containing Any",
  2194. inputMessage: &anypb.Any{},
  2195. inputText: `{
  2196. "@type": "pb2.KnownTypes",
  2197. "optAny": {
  2198. "@type": "google.protobuf.StringValue",
  2199. "value": "` + "abc\xff" + `"
  2200. }
  2201. }`,
  2202. wantErr: true,
  2203. }, {
  2204. desc: "well known types as field values",
  2205. inputMessage: &pb2.KnownTypes{},
  2206. inputText: `{
  2207. "optBool": false,
  2208. "optInt32": 42,
  2209. "optInt64": "42",
  2210. "optUint32": 42,
  2211. "optUint64": "42",
  2212. "optFloat": 1.23,
  2213. "optDouble": 3.1415,
  2214. "optString": "hello",
  2215. "optBytes": "aGVsbG8=",
  2216. "optDuration": "123s",
  2217. "optTimestamp": "2019-03-19T23:03:21Z",
  2218. "optStruct": {
  2219. "string": "hello"
  2220. },
  2221. "optList": [
  2222. null,
  2223. "",
  2224. {},
  2225. []
  2226. ],
  2227. "optValue": "world",
  2228. "optEmpty": {},
  2229. "optAny": {
  2230. "@type": "google.protobuf.Empty",
  2231. "value": {}
  2232. },
  2233. "optFieldmask": "fooBar,barFoo"
  2234. }`,
  2235. wantMessage: &pb2.KnownTypes{
  2236. OptBool: &wrapperspb.BoolValue{Value: false},
  2237. OptInt32: &wrapperspb.Int32Value{Value: 42},
  2238. OptInt64: &wrapperspb.Int64Value{Value: 42},
  2239. OptUint32: &wrapperspb.UInt32Value{Value: 42},
  2240. OptUint64: &wrapperspb.UInt64Value{Value: 42},
  2241. OptFloat: &wrapperspb.FloatValue{Value: 1.23},
  2242. OptDouble: &wrapperspb.DoubleValue{Value: 3.1415},
  2243. OptString: &wrapperspb.StringValue{Value: "hello"},
  2244. OptBytes: &wrapperspb.BytesValue{Value: []byte("hello")},
  2245. OptDuration: &durationpb.Duration{Seconds: 123},
  2246. OptTimestamp: &timestamppb.Timestamp{Seconds: 1553036601},
  2247. OptStruct: &structpb.Struct{
  2248. Fields: map[string]*structpb.Value{
  2249. "string": {Kind: &structpb.Value_StringValue{"hello"}},
  2250. },
  2251. },
  2252. OptList: &structpb.ListValue{
  2253. Values: []*structpb.Value{
  2254. {Kind: &structpb.Value_NullValue{}},
  2255. {Kind: &structpb.Value_StringValue{}},
  2256. {
  2257. Kind: &structpb.Value_StructValue{
  2258. &structpb.Struct{Fields: map[string]*structpb.Value{}},
  2259. },
  2260. },
  2261. {
  2262. Kind: &structpb.Value_ListValue{
  2263. &structpb.ListValue{Values: []*structpb.Value{}},
  2264. },
  2265. },
  2266. },
  2267. },
  2268. OptValue: &structpb.Value{
  2269. Kind: &structpb.Value_StringValue{"world"},
  2270. },
  2271. OptEmpty: &emptypb.Empty{},
  2272. OptAny: &anypb.Any{
  2273. TypeUrl: "google.protobuf.Empty",
  2274. },
  2275. OptFieldmask: &fieldmaskpb.FieldMask{
  2276. Paths: []string{"foo_bar", "bar_foo"},
  2277. },
  2278. },
  2279. }, {
  2280. desc: "DiscardUnknown: regular messages",
  2281. umo: protojson.UnmarshalOptions{DiscardUnknown: true},
  2282. inputMessage: &pb3.Nests{},
  2283. inputText: `{
  2284. "sNested": {
  2285. "unknown": {
  2286. "foo": 1,
  2287. "bar": [1, 2, 3]
  2288. }
  2289. },
  2290. "unknown": "not known"
  2291. }`,
  2292. wantMessage: &pb3.Nests{SNested: &pb3.Nested{}},
  2293. }, {
  2294. desc: "DiscardUnknown: repeated",
  2295. umo: protojson.UnmarshalOptions{DiscardUnknown: true},
  2296. inputMessage: &pb2.Nests{},
  2297. inputText: `{
  2298. "rptNested": [
  2299. {"unknown": "blah"},
  2300. {"optString": "hello"}
  2301. ]
  2302. }`,
  2303. wantMessage: &pb2.Nests{
  2304. RptNested: []*pb2.Nested{
  2305. {},
  2306. {OptString: proto.String("hello")},
  2307. },
  2308. },
  2309. }, {
  2310. desc: "DiscardUnknown: map",
  2311. umo: protojson.UnmarshalOptions{DiscardUnknown: true},
  2312. inputMessage: &pb3.Maps{},
  2313. inputText: `{
  2314. "strToNested": {
  2315. "nested_one": {
  2316. "unknown": "what you see is not"
  2317. }
  2318. }
  2319. }`,
  2320. wantMessage: &pb3.Maps{
  2321. StrToNested: map[string]*pb3.Nested{
  2322. "nested_one": {},
  2323. },
  2324. },
  2325. }, {
  2326. desc: "DiscardUnknown: extension",
  2327. umo: protojson.UnmarshalOptions{DiscardUnknown: true},
  2328. inputMessage: &pb2.Extensions{},
  2329. inputText: `{
  2330. "[pb2.opt_ext_nested]": {
  2331. "unknown": []
  2332. }
  2333. }`,
  2334. wantMessage: func() proto.Message {
  2335. m := &pb2.Extensions{}
  2336. proto.SetExtension(m, pb2.E_OptExtNested, &pb2.Nested{})
  2337. return m
  2338. }(),
  2339. }, {
  2340. desc: "DiscardUnknown: Empty",
  2341. umo: protojson.UnmarshalOptions{DiscardUnknown: true},
  2342. inputMessage: &emptypb.Empty{},
  2343. inputText: `{"unknown": "something"}`,
  2344. wantMessage: &emptypb.Empty{},
  2345. }, {
  2346. desc: "DiscardUnknown: Any without type",
  2347. umo: protojson.UnmarshalOptions{DiscardUnknown: true},
  2348. inputMessage: &anypb.Any{},
  2349. inputText: `{
  2350. "value": {"foo": "bar"},
  2351. "unknown": true
  2352. }`,
  2353. wantMessage: &anypb.Any{},
  2354. }, {
  2355. desc: "DiscardUnknown: Any",
  2356. umo: protojson.UnmarshalOptions{
  2357. DiscardUnknown: true,
  2358. },
  2359. inputMessage: &anypb.Any{},
  2360. inputText: `{
  2361. "@type": "foo/pb2.Nested",
  2362. "unknown": "none"
  2363. }`,
  2364. wantMessage: &anypb.Any{
  2365. TypeUrl: "foo/pb2.Nested",
  2366. },
  2367. }, {
  2368. desc: "DiscardUnknown: Any with Empty",
  2369. umo: protojson.UnmarshalOptions{
  2370. DiscardUnknown: true,
  2371. },
  2372. inputMessage: &anypb.Any{},
  2373. inputText: `{
  2374. "@type": "type.googleapis.com/google.protobuf.Empty",
  2375. "value": {"unknown": 47}
  2376. }`,
  2377. wantMessage: &anypb.Any{
  2378. TypeUrl: "type.googleapis.com/google.protobuf.Empty",
  2379. },
  2380. }, {
  2381. desc: "weak fields",
  2382. inputMessage: &testpb.TestWeak{},
  2383. inputText: `{"weak_message1":{"a":1}}`,
  2384. wantMessage: func() *testpb.TestWeak {
  2385. m := new(testpb.TestWeak)
  2386. m.SetWeakMessage1(&weakpb.WeakImportMessage1{A: proto.Int32(1)})
  2387. return m
  2388. }(),
  2389. skip: !flags.ProtoLegacy,
  2390. }, {
  2391. desc: "weak fields; unknown field",
  2392. inputMessage: &testpb.TestWeak{},
  2393. inputText: `{"weak_message1":{"a":1}, "weak_message2":{"a":1}}`,
  2394. wantErr: true, // weak_message2 is unknown since the package containing it is not imported
  2395. skip: !flags.ProtoLegacy,
  2396. }}
  2397. for _, tt := range tests {
  2398. tt := tt
  2399. if tt.skip {
  2400. continue
  2401. }
  2402. t.Run(tt.desc, func(t *testing.T) {
  2403. err := tt.umo.Unmarshal([]byte(tt.inputText), tt.inputMessage)
  2404. if err != nil && !tt.wantErr {
  2405. t.Errorf("Unmarshal() returned error: %v\n\n", err)
  2406. }
  2407. if err == nil && tt.wantErr {
  2408. t.Error("Unmarshal() got nil error, want error\n\n")
  2409. }
  2410. if tt.wantMessage != nil && !proto.Equal(tt.inputMessage, tt.wantMessage) {
  2411. t.Errorf("Unmarshal()\n<got>\n%v\n<want>\n%v\n", tt.inputMessage, tt.wantMessage)
  2412. }
  2413. })
  2414. }
  2415. }