• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2015-2016 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #include <string.h>
20 
21 #include <grpc/support/alloc.h>
22 #include <grpc/support/log.h>
23 #include <grpc/support/string_util.h>
24 #include "src/core/lib/gpr/string.h"
25 #include "src/core/lib/gpr/useful.h"
26 #include "src/core/lib/json/json.h"
27 
28 #include "test/core/util/test_config.h"
29 
30 typedef struct testing_pair {
31   const char* input;
32   const char* output;
33 } testing_pair;
34 
35 static testing_pair testing_pairs[] = {
36     /* Testing valid parsing. */
37     /* Testing trivial parses, with de-indentation. */
38     {" 0 ", "0"},
39     {" 1 ", "1"},
40     {" \"    \" ", "\"    \""},
41     {" \"a\" ", "\"a\""},
42     {" true ", "true"},
43     /* Testing the parser's ability to decode trivial UTF-16. */
44     {"\"\\u0020\\\\\\u0010\\u000a\\u000D\"", "\" \\\\\\u0010\\n\\r\""},
45     /* Testing various UTF-8 sequences. */
46     {"\"ßâñć௵⇒\"", "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\""},
47     {"\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"",
48      "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\""},
49     /* Testing UTF-8 character "��", U+11D1E. */
50     {"\"\xf0\x9d\x84\x9e\"", "\"\\ud834\\udd1e\""},
51     {"\"\\ud834\\udd1e\"", "\"\\ud834\\udd1e\""},
52     {"{\"\\ud834\\udd1e\":0}", "{\"\\ud834\\udd1e\":0}"},
53     /* Testing nested empty containers. */
54     {
55         " [ [ ] , { } , [ ] ] ",
56         "[[],{},[]]",
57     },
58     /* Testing escapes and control chars in key strings. */
59     {" { \"\\u007f\x7f\\n\\r\\\"\\f\\b\\\\a , b\": 1, \"\": 0 } ",
60      "{\"\\u007f\\u007f\\n\\r\\\"\\f\\b\\\\a , b\":1,\"\":0}"},
61     /* Testing the writer's ability to cut off invalid UTF-8 sequences. */
62     {"\"abc\xf0\x9d\x24\"", "\"abc\""},
63     {"\"\xff\"", "\"\""},
64     /* Testing valid number parsing. */
65     {"[0, 42 , 0.0123, 123.456]", "[0,42,0.0123,123.456]"},
66     {"[1e4,-53.235e-31, 0.3e+3]", "[1e4,-53.235e-31,0.3e+3]"},
67     /* Testing keywords parsing. */
68     {"[true, false, null]", "[true,false,null]"},
69 
70     /* Testing invalid parsing. */
71 
72     /* Testing plain invalid things, exercising the state machine. */
73     {"\\", nullptr},
74     {"nu ll", nullptr},
75     {"{\"foo\": bar}", nullptr},
76     {"{\"foo\": bar\"x\"}", nullptr},
77     {"fals", nullptr},
78     {"0,0 ", nullptr},
79     {"\"foo\",[]", nullptr},
80     /* Testing unterminated string. */
81     {"\"\\x", nullptr},
82     /* Testing invalid UTF-16 number. */
83     {"\"\\u123x", nullptr},
84     {"{\"\\u123x", nullptr},
85     /* Testing imbalanced surrogate pairs. */
86     {"\"\\ud834f", nullptr},
87     {"{\"\\ud834f\":0}", nullptr},
88     {"\"\\ud834\\n", nullptr},
89     {"{\"\\ud834\\n\":0}", nullptr},
90     {"\"\\udd1ef", nullptr},
91     {"{\"\\udd1ef\":0}", nullptr},
92     {"\"\\ud834\\ud834\"", nullptr},
93     {"{\"\\ud834\\ud834\"\":0}", nullptr},
94     {"\"\\ud834\\u1234\"", nullptr},
95     {"{\"\\ud834\\u1234\"\":0}", nullptr},
96     {"\"\\ud834]\"", nullptr},
97     {"{\"\\ud834]\"\":0}", nullptr},
98     {"\"\\ud834 \"", nullptr},
99     {"{\"\\ud834 \"\":0}", nullptr},
100     {"\"\\ud834\\\\\"", nullptr},
101     {"{\"\\ud834\\\\\"\":0}", nullptr},
102     /* Testing embedded invalid whitechars. */
103     {"\"\n\"", nullptr},
104     {"\"\t\"", nullptr},
105     /* Testing empty json data. */
106     {"", nullptr},
107     /* Testing extra characters after end of parsing. */
108     {"{},", nullptr},
109     /* Testing imbalanced containers. */
110     {"{}}", nullptr},
111     {"[]]", nullptr},
112     {"{{}", nullptr},
113     {"[[]", nullptr},
114     {"[}", nullptr},
115     {"{]", nullptr},
116     /* Testing bad containers. */
117     {"{x}", nullptr},
118     {"{x=0,y}", nullptr},
119     /* Testing trailing comma. */
120     {"{,}", nullptr},
121     {"[1,2,3,4,]", nullptr},
122     {"{\"a\": 1, }", nullptr},
123     /* Testing after-ending characters. */
124     {"{}x", nullptr},
125     /* Testing having a key syntax in an array. */
126     {"[\"x\":0]", nullptr},
127     /* Testing invalid numbers. */
128     {"1.", nullptr},
129     {"1e", nullptr},
130     {".12", nullptr},
131     {"1.x", nullptr},
132     {"1.12x", nullptr},
133     {"1ex", nullptr},
134     {"1e12x", nullptr},
135     {".12x", nullptr},
136     {"000", nullptr},
137 };
138 
test_pairs()139 static void test_pairs() {
140   unsigned i;
141 
142   for (i = 0; i < GPR_ARRAY_SIZE(testing_pairs); i++) {
143     testing_pair* pair = testing_pairs + i;
144     char* scratchpad = gpr_strdup(pair->input);
145     grpc_json* json;
146 
147     gpr_log(GPR_INFO, "parsing string %i - should %s", i,
148             pair->output ? "succeed" : "fail");
149     json = grpc_json_parse_string(scratchpad);
150 
151     if (pair->output) {
152       char* output;
153 
154       GPR_ASSERT(json);
155       output = grpc_json_dump_to_string(json, 0);
156       GPR_ASSERT(output);
157       gpr_log(GPR_INFO, "succeeded with output = %s", output);
158       GPR_ASSERT(strcmp(output, pair->output) == 0);
159 
160       grpc_json_destroy(json);
161       gpr_free(output);
162     } else {
163       gpr_log(GPR_INFO, "failed");
164       GPR_ASSERT(!json);
165     }
166 
167     gpr_free(scratchpad);
168   }
169 }
170 
test_atypical()171 static void test_atypical() {
172   char* scratchpad = gpr_strdup("[[],[],[]]");
173   grpc_json* json = grpc_json_parse_string(scratchpad);
174   grpc_json* brother;
175 
176   GPR_ASSERT(json);
177   GPR_ASSERT(json->child);
178   brother = json->child->next;
179   grpc_json_destroy(json->child);
180   GPR_ASSERT(json->child == brother);
181   grpc_json_destroy(json->child->next);
182   grpc_json_destroy(json);
183   gpr_free(scratchpad);
184 }
185 
main(int argc,char ** argv)186 int main(int argc, char** argv) {
187   grpc_test_init(argc, argv);
188   test_pairs();
189   test_atypical();
190   gpr_log(GPR_INFO, "json_test success");
191   return 0;
192 }
193