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