Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include <string.h>
35 :
36 : #include <grpc/support/alloc.h>
37 : #include <grpc/support/useful.h>
38 : #include <grpc/support/log.h>
39 : #include <grpc/support/string_util.h>
40 : #include "src/core/json/json.h"
41 : #include "src/core/support/string.h"
42 :
43 : #include "test/core/util/test_config.h"
44 :
45 : typedef struct testing_pair {
46 : const char *input;
47 : const char *output;
48 : } testing_pair;
49 :
50 : static testing_pair testing_pairs[] = {
51 : /* Testing valid parsing. */
52 :
53 : /* Testing trivial parses, with de-indentation. */
54 : {" 0 ", "0"},
55 : {" 1 ", "1"},
56 : {" \"a\" ", "\"a\""},
57 : {" true ", "true"},
58 : /* Testing the parser's ability to decode trivial UTF-16. */
59 : {"\"\\u0020\\\\\\u0010\\u000a\\u000D\"", "\" \\\\\\u0010\\n\\r\""},
60 : /* Testing various UTF-8 sequences. */
61 : {"\"ßâñć௵⇒\"", "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\""},
62 : {"\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"",
63 : "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\""},
64 : /* Testing UTF-8 character "𝄞", U+11D1E. */
65 : {"\"\xf0\x9d\x84\x9e\"", "\"\\ud834\\udd1e\""},
66 : {"\"\\ud834\\udd1e\"", "\"\\ud834\\udd1e\""},
67 : /* Testing nested empty containers. */
68 : {
69 : " [ [ ] , { } , [ ] ] ", "[[],{},[]]",
70 : },
71 : /* Testing escapes and control chars in key strings. */
72 : {" { \"\x7f\\n\\\\a , b\": 1, \"\": 0 } ",
73 : "{\"\\u007f\\n\\\\a , b\":1,\"\":0}"},
74 : /* Testing the writer's ability to cut off invalid UTF-8 sequences. */
75 : {"\"abc\xf0\x9d\x24\"", "\"abc\""},
76 : {"\"\xff\"", "\"\""},
77 : /* Testing valid number parsing. */
78 : {"[0, 42 , 0.0123, 123.456]", "[0,42,0.0123,123.456]"},
79 : {"[1e4,-53.235e-31, 0.3e+3]", "[1e4,-53.235e-31,0.3e+3]"},
80 : /* Testing keywords parsing. */
81 : {"[true, false, null]", "[true,false,null]"},
82 :
83 : /* Testing invalid parsing. */
84 :
85 : /* Testing plain invalid things, exercising the state machine. */
86 : {"\\", NULL},
87 : {"nu ll", NULL},
88 : {"fals", NULL},
89 : /* Testing unterminated string. */
90 : {"\"\\x", NULL},
91 : /* Testing invalid UTF-16 number. */
92 : {"\"\\u123x", NULL},
93 : /* Testing imbalanced surrogate pairs. */
94 : {"\"\\ud834f", NULL},
95 : {"\"\\ud834\\n", NULL},
96 : {"\"\\udd1ef", NULL},
97 : {"\"\\ud834\\ud834\"", NULL},
98 : {"\"\\ud834\\u1234\"", NULL},
99 : /* Testing embedded invalid whitechars. */
100 : {"\"\n\"", NULL},
101 : {"\"\t\"", NULL},
102 : /* Testing empty json data. */
103 : {"", NULL},
104 : /* Testing extra characters after end of parsing. */
105 : {"{},", NULL},
106 : /* Testing imbalanced containers. */
107 : {"{}}", NULL},
108 : {"[]]", NULL},
109 : {"{{}", NULL},
110 : {"[[]", NULL},
111 : {"[}", NULL},
112 : {"{]", NULL},
113 : /*Testing trailing comma. */
114 : {"{,}", NULL},
115 : {"[1,2,3,4,]", NULL},
116 : /* Testing having a key syntax in an array. */
117 : {"[\"x\":0]", NULL},
118 : /* Testing invalid numbers. */
119 : {"1.", NULL},
120 : {"1e", NULL},
121 : {".12", NULL},
122 : {"1.x", NULL},
123 : {"1.12x", NULL},
124 : {"1ex", NULL},
125 : {"1e12x", NULL},
126 : {".12x", NULL},
127 : {"000", NULL},
128 : };
129 :
130 1 : static void test_pairs() {
131 : unsigned i;
132 :
133 49 : for (i = 0; i < GPR_ARRAY_SIZE(testing_pairs); i++) {
134 48 : testing_pair *pair = testing_pairs + i;
135 48 : char *scratchpad = gpr_strdup(pair->input);
136 : grpc_json *json;
137 :
138 48 : gpr_log(GPR_INFO, "parsing string %i - should %s", i,
139 48 : pair->output ? "succeed" : "fail");
140 48 : json = grpc_json_parse_string(scratchpad);
141 :
142 48 : if (pair->output) {
143 : char *output;
144 :
145 16 : GPR_ASSERT(json);
146 16 : output = grpc_json_dump_to_string(json, 0);
147 16 : GPR_ASSERT(output);
148 16 : gpr_log(GPR_INFO, "succeeded with output = %s", output);
149 16 : GPR_ASSERT(strcmp(output, pair->output) == 0);
150 :
151 16 : grpc_json_destroy(json);
152 16 : gpr_free(output);
153 : } else {
154 32 : gpr_log(GPR_INFO, "failed");
155 32 : GPR_ASSERT(!json);
156 : }
157 :
158 48 : gpr_free(scratchpad);
159 : }
160 1 : }
161 :
162 1 : static void test_atypical() {
163 1 : char *scratchpad = gpr_strdup("[[],[]]");
164 1 : grpc_json *json = grpc_json_parse_string(scratchpad);
165 : grpc_json *brother;
166 :
167 1 : GPR_ASSERT(json);
168 1 : GPR_ASSERT(json->child);
169 1 : brother = json->child->next;
170 1 : grpc_json_destroy(json->child);
171 1 : json->child = brother;
172 1 : grpc_json_destroy(json);
173 1 : gpr_free(scratchpad);
174 1 : }
175 :
176 1 : int main(int argc, char **argv) {
177 1 : grpc_test_init(argc, argv);
178 1 : test_pairs();
179 1 : test_atypical();
180 1 : gpr_log(GPR_INFO, "json_test success");
181 1 : return 0;
182 : }
|