• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include "upb/json/decode.h"
9 
10 #include <string>
11 #include <vector>
12 
13 #include "google/protobuf/struct.upb.h"
14 #include <gtest/gtest.h>
15 #include "upb/base/status.hpp"
16 #include "upb/base/upcast.h"
17 #include "upb/json/test.upb.h"
18 #include "upb/json/test.upbdefs.h"
19 #include "upb/mem/arena.h"
20 #include "upb/mem/arena.hpp"
21 #include "upb/reflection/def.hpp"
22 
JsonDecode(const char * json,upb_Arena * a)23 static upb_test_Box* JsonDecode(const char* json, upb_Arena* a) {
24   upb::Status status;
25   upb::DefPool defpool;
26   upb::MessageDefPtr m(upb_test_Box_getmsgdef(defpool.ptr()));
27   EXPECT_TRUE(m.ptr() != nullptr);
28 
29   upb_test_Box* box = upb_test_Box_new(a);
30   int options = 0;
31   bool ok = upb_JsonDecode(json, strlen(json), UPB_UPCAST(box), m.ptr(),
32                            defpool.ptr(), options, a, status.ptr());
33   return ok ? box : nullptr;
34 }
35 
36 struct FloatTest {
37   const std::string json;
38   float f;
39 };
40 
41 static const std::vector<FloatTest> FloatTestsPass = {
42     {R"({"f": 0})", 0},
43     {R"({"f": 1})", 1},
44     {R"({"f": 1.000000})", 1},
45     {R"({"f": 1.5e1})", 15},
46     {R"({"f": 15e-1})", 1.5},
47     {R"({"f": -3.5})", -3.5},
48     {R"({"f": 3.402823e38})", 3.402823e38},
49     {R"({"f": -3.402823e38})", -3.402823e38},
50     {R"({"f": 340282346638528859811704183484516925440.0})",
51      340282346638528859811704183484516925440.0},
52     {R"({"f": -340282346638528859811704183484516925440.0})",
53      -340282346638528859811704183484516925440.0},
54 };
55 
56 static const std::vector<FloatTest> FloatTestsFail = {
57     {R"({"f": 1z})", 0},
58     {R"({"f": 3.4028236e+38})", 0},
59     {R"({"f": -3.4028236e+38})", 0},
60 };
61 
62 // Decode some floats.
TEST(JsonTest,DecodeFloats)63 TEST(JsonTest, DecodeFloats) {
64   upb::Arena a;
65 
66   for (const auto& test : FloatTestsPass) {
67     upb_test_Box* box = JsonDecode(test.json.c_str(), a.ptr());
68     EXPECT_NE(box, nullptr);
69     float f = upb_test_Box_f(box);
70     EXPECT_EQ(f, test.f);
71   }
72 
73   for (const auto& test : FloatTestsFail) {
74     upb_test_Box* box = JsonDecode(test.json.c_str(), a.ptr());
75     EXPECT_EQ(box, nullptr);
76   }
77 }
78 
TEST(JsonTest,DecodeConflictJsonName)79 TEST(JsonTest, DecodeConflictJsonName) {
80   upb::Arena a;
81   std::string json_string = R"({"value": 2})";
82   upb_test_Box* box = JsonDecode(json_string.c_str(), a.ptr());
83   EXPECT_EQ(2, upb_test_Box_new_value(box));
84   EXPECT_EQ(0, upb_test_Box_value(box));
85 }
86 
TEST(JsonTest,RejectsBadTrailingCharacters)87 TEST(JsonTest, RejectsBadTrailingCharacters) {
88   upb::Arena a;
89   std::string json_string = R"({}abc)";
90   upb_test_Box* box = JsonDecode(json_string.c_str(), a.ptr());
91   EXPECT_EQ(box, nullptr);
92 }
93 
TEST(JsonTest,AcceptsTrailingWhitespace)94 TEST(JsonTest, AcceptsTrailingWhitespace) {
95   upb::Arena a;
96   std::string json_string = "{} \n \r\n \t\t";
97   upb_test_Box* box = JsonDecode(json_string.c_str(), a.ptr());
98   EXPECT_NE(box, nullptr);
99 }
100