1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include "precompiled.hpp" 26 #include "prims/jvm.h" 27 #include "utilities/json.hpp" 28 #include "unittest.hpp" 29 30 class JSON_GTest : public JSON { 31 public: 32 static void test(const char* json, bool valid); 33 34 private: 35 JSON_GTest(const char* text); 36 37 void log(uint level, const char* format, ...) ATTRIBUTE_PRINTF(3, 4); 38 39 bool callback(JSON_TYPE t, JSON_VAL* v, uint level); 40 JSON_TYPE prev; 41 }; 42 43 void JSON_GTest::test(const char* text, bool should_pass) { 44 JSON_GTest json(text); 45 if (should_pass) { 46 ASSERT_TRUE(json.valid()) << "failed on a valid json string"; 47 } else { 48 ASSERT_FALSE(json.valid()) << "succeeded on an invalid json string"; 49 } 50 } 51 52 JSON_GTest::JSON_GTest(const char* text) : JSON(text, false, tty) { 53 prev = JSON_NONE; 54 parse(); 55 } 56 57 TEST_VM(utilities, json_curly_braces) { 58 JSON_GTest::test("{}", true); 59 } 60 61 TEST_VM(utilities, json_brackets) { 62 JSON_GTest::test("[]", true); 63 } 64 65 TEST_VM(utilities, json_space_braces) { 66 JSON_GTest::test(" { } ", true); 67 } 68 69 TEST_VM(utilities, json_space_bracketes) { 70 JSON_GTest::test(" [ ] ", true); 71 } 72 73 TEST_VM(utilities, json_quoted_error) { 74 JSON_GTest::test("\"error\"", false); 75 } 76 77 TEST_VM(utilities, json_error_string) { 78 JSON_GTest::test("error", false); 79 } 80 81 TEST_VM(utilities, json_simple_integer) { 82 JSON_GTest::test("1", false); 83 } 84 85 TEST_VM(utilities, json_siple_float) { 86 JSON_GTest::test("1.2", false); 87 } 88 89 TEST_VM(utilities, json_simple_boolean_true) { 90 JSON_GTest::test("true", false); 91 } 92 93 TEST_VM(utilities, json_simple_boolean_false) { 94 JSON_GTest::test("false", false); 95 } 96 97 TEST_VM(utilities, json_simple_null) { 98 JSON_GTest::test("null", false); 99 } 100 101 TEST_VM(utilities, json_one_element_int_array) { 102 JSON_GTest::test("[ 1 ]", true); 103 } 104 105 TEST_VM(utilities, json_int_array) { 106 JSON_GTest::test("[ 1, ]", true); 107 } 108 109 TEST_VM(utilities, json_one_element_bool_array) { 110 JSON_GTest::test("[ true ]", true); 111 } 112 113 TEST_VM(utilities, json_bool_array) { 114 JSON_GTest::test("[ true, ]", true); 115 } 116 117 TEST_VM(utilities, json_one_element_false_array) { 118 JSON_GTest::test("[ false ]", true); 119 } 120 121 TEST_VM(utilities, json_false_bool_array) { 122 JSON_GTest::test("[ false, ]", true); 123 } 124 125 TEST_VM(utilities, json_one_null_array) { 126 JSON_GTest::test("[ null ]", true); 127 } 128 129 TEST_VM(utilities, json_null_array) { 130 JSON_GTest::test("[ null, ]", true); 131 } 132 133 TEST_VM(utilities, json_one_empty_string_array) { 134 JSON_GTest::test("[ \"\" ]", true); 135 } 136 137 TEST_VM(utilities, json_empty_string_array) { 138 JSON_GTest::test("[ \"\", ]", true); 139 } 140 141 TEST_VM(utilities, json_single_string_array) { 142 JSON_GTest::test("[ \"elem1\" ]", true); 143 } 144 145 TEST_VM(utilities, json_string_comma_arrray) { 146 JSON_GTest::test("[ \"elem1\", ]", true); 147 } 148 149 TEST_VM(utilities, json_two_strings_array) { 150 JSON_GTest::test("[ \"elem1\", \"elem2\" ]", true); 151 } 152 153 TEST_VM(utilities, json_two_strings_comma_array) { 154 JSON_GTest::test("[ \"elem1\", \"elem2\", ]", true); 155 } 156 157 TEST_VM(utilities, json_curly_braces_outside) { 158 JSON_GTest::test("[ \"elem1\" ] { }", false); 159 } 160 161 TEST_VM(utilities, json_element_in_array) { 162 JSON_GTest::test("[ elem1, \"elem2\" ]", false); 163 } 164 165 TEST_VM(utilities, json_incorrect_end_array) { 166 JSON_GTest::test("[ \"elem1\"", false); 167 } 168 169 TEST_VM(utilities, json_incorrect_string_end) { 170 JSON_GTest::test("[ \"elem1 ]", false); 171 } 172 173 TEST_VM(utilities, json_incorrect_end_of_two_elements_array) { 174 JSON_GTest::test("[ \"elem1\", \"elem2\"", false); 175 } 176 177 TEST_VM(utilities, json_incorrect_bool_true_array) { 178 JSON_GTest::test("[ truefoo ]", false); 179 } 180 181 TEST_VM(utilities, json_incorrect_bool_false_array) { 182 JSON_GTest::test("[ falsefoo ]", false); 183 } 184 185 TEST_VM(utilities, json_incorrect_null_array) { 186 JSON_GTest::test("[ nullfoo ]", false); 187 } 188 189 TEST_VM(utilities, json_key_pair) { 190 JSON_GTest::test("{ key : 1 }", true); 191 } 192 193 TEST_VM(utilities, json_key_pair_comma) { 194 JSON_GTest::test("{ key : 1, }", true); 195 } 196 197 TEST_VM(utilities, json_bool_true_key) { 198 JSON_GTest::test("{ key : true }", true); 199 } 200 201 TEST_VM(utilities, json_bool_true_key_comma) { 202 JSON_GTest::test("{ key : true, }", true); 203 } 204 205 TEST_VM(utilities, json_bool_false_key) { 206 JSON_GTest::test("{ key : false }", true); 207 } 208 209 TEST_VM(utilities, json_bool_false_key_comma) { 210 JSON_GTest::test("{ key : false, }", true); 211 } 212 213 TEST_VM(utilities, json_null_key) { 214 JSON_GTest::test("{ key : null }", true); 215 } 216 217 TEST_VM(utilities, json_null_key_comma) { 218 JSON_GTest::test("{ key : null, }", true); 219 } 220 221 TEST_VM(utilities, json_pair_of_empty_strings) { 222 JSON_GTest::test("{ \"\" : \"\" }", true); 223 } 224 225 TEST_VM(utilities, json_pair_of_empty_strings_comma) { 226 JSON_GTest::test("{ \"\" : \"\", }", true); 227 } 228 229 TEST_VM(utilities, json_pair_of_strings) { 230 JSON_GTest::test("{ \"key1\" : \"val1\" }", true); 231 } 232 233 TEST_VM(utilities, json_pair_of_strings_comma) { 234 JSON_GTest::test("{ \"key1\" : \"val1\", }", true); 235 } 236 237 TEST_VM(utilities, json_two_pairs_of_strings) { 238 JSON_GTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\" }", true); 239 } 240 241 TEST_VM(utilities, json_two_pairs_of_strings_comma) { 242 JSON_GTest::test("{ \"key1\" : \"val1\", \"key2\" : \"val2\", }", true); 243 } 244 245 TEST_VM(utilities, json_array_outside) { 246 JSON_GTest::test("{ \"key\" : \"val\" } [ \"error\" ]", false); 247 } 248 249 TEST_VM(utilities, json_incorrect_object_end) { 250 JSON_GTest::test("{ \"key\" : \"val\" ", false); 251 } 252 253 TEST_VM(utilities, json_empty_comment) { 254 JSON_GTest::test("/**/ { }", true); 255 } 256 257 TEST_VM(utilities, json_space_comment) { 258 JSON_GTest::test("/* */ { }", true); 259 } 260 261 TEST_VM(utilities, json_comment) { 262 JSON_GTest::test("/*foo*/ { }", true); 263 } 264 265 TEST_VM(utilities, json_star_comment) { 266 JSON_GTest::test("/* *foo */ { }", true); 267 } 268 269 TEST_VM(utilities, json_stars_comment) { 270 JSON_GTest::test("/* *foo* */ { }", true); 271 } 272 273 TEST_VM(utilities, json_special_comment) { 274 JSON_GTest::test("/* /*foo */ { }", true); 275 } 276 277 TEST_VM(utilities, json_comment_after) { 278 JSON_GTest::test("{ } /* foo */", true); 279 } 280 281 TEST_VM(utilities, json_comment_after_and_space) { 282 JSON_GTest::test("{ } /* foo */ ", true); 283 } 284 285 TEST_VM(utilities, json_one_line_empty_comment_after) { 286 JSON_GTest::test("{ } //", true); 287 } 288 289 TEST_VM(utilities, json_one_line_space_comment_after) { 290 JSON_GTest::test("{ } // ", true); 291 } 292 293 TEST_VM(utilities, json_one_line_comment_after) { 294 JSON_GTest::test("{ } // foo", true); 295 } 296 297 TEST_VM(utilities, json_incorrect_multiline_comment) { 298 JSON_GTest::test("/* * / { }", false); 299 } 300 301 TEST_VM(utilities, json_incorrect_multiline_comment_begin) { 302 JSON_GTest::test("/ * */ { }", false); 303 } 304 305 TEST_VM(utilities, json_oneline_comment_only) { 306 JSON_GTest::test("// { }", false); 307 } 308 309 TEST_VM(utilities, json_multiline_comment_only) { 310 JSON_GTest::test("/* { } */", false); 311 } 312 313 TEST_VM(utilities, json_multiline_comment_2) { 314 JSON_GTest::test("/* { } */ ", false); 315 } 316 317 TEST_VM(utilities, json_incorrectly_commented_object) { 318 JSON_GTest::test("/* { } ", false); 319 } 320 321 TEST_VM(utilities, json_missing_multiline_end) { 322 JSON_GTest::test("{ } /* ", false); 323 } 324 325 TEST_VM(utilities, json_missing_multiline_slash) { 326 JSON_GTest::test("/* { } *", false); 327 } 328 329 TEST_VM(utilities, json_commented_object_end) { 330 JSON_GTest::test("{ /* } */", false); 331 } 332 333 TEST_VM(utilities, json_commented_array_end) { 334 JSON_GTest::test("[ /* ] */", false); 335 } 336 337 TEST_VM(utilities, json_missing_object_end) { 338 JSON_GTest::test("{ key : \"val\", /* } */", false); 339 } 340 341 TEST_VM(utilities, json_missing_array_end) { 342 JSON_GTest::test("[ \"val\", /* ] */", false); 343 } 344 345 TEST_VM(utilities, json_key_values_1) { 346 JSON_GTest::test("/* comment */{ key1 : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\"," 347 "{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\"" 348 " : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); 349 } 350 351 TEST_VM(utilities, json_key_values_2) { 352 JSON_GTest::test("/* comment */ { \"key1\" : { \"key2\" : { \"key3\" : [ \"elem1\", \"elem2\"," 353 "{ \"key4\" : null }, 3 , 2 , 1 , 0 , -1 , -2 , -3 , true, false, null, ] }, \"key5\"" 354 " : true }, \"key6\" : [ \"☃\" ], key7 : \"val\",}", true); 355 } 356 357 TEST_VM(utilities, json_quoted_symbols) { 358 JSON_GTest::test("/*comment*/{\"ff1 fsd\":{\"☃\":{\"☃\":[\"☃\",\"☃\"]}," 359 "\"☃\":true},\"☃\":[\"☃\"],\"foo\":\"☃\",}", true); 360 } 361 362 TEST_VM(utilities, json_incorrect_key) { 363 JSON_GTest::test("/* comment */ { key1 error : { \"☃\" : { \"☃\" : [ \"☃\"," 364 " \"☃\" ] }, \"☃\" : true }, \"baz\" : [ \"☃\" ], foo : \"☃\",}", 365 false); // first key needs to be quoted since it contains a space 366 } 367 368 TEST_VM(utilities, json_array_with_newline) { 369 JSON_GTest::test("[\n]", true); 370 } 371 372 TEST_VM(utilities, json_directives_file) { 373 JSON_GTest::test( 374 "[" "\n" 375 " {" 376 " // pattern to match against class+method+signature" "\n" 377 " // leading and trailing wildcard (*) allowed" "\n" 378 " match: \"foo.bar.*\"," "\n" 379 " " "\n" 380 " // override defaults for specified compiler" "\n" 381 " // we may differentiate between levels too. TBD." "\n" 382 " c1: {" "\n" 383 " //override c1 presets " "\n" 384 " array_bounds_check_removal: false" "\n" 385 " }," "\n" 386 "" "\n" 387 " c2: {" "\n" 388 " // control inlining of method" "\n" 389 " // + force inline, - dont inline" "\n" 390 " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" 391 " }," "\n" 392 "" "\n" 393 " // directives outside a specific preset applies to all compilers" "\n" 394 " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" 395 " print_assembly: true," "\n" 396 " verify_oopmaps: true," "\n" 397 " max_loop_unrolling: 5" "\n" 398 " }," "\n" 399 " {" "\n" 400 " // matching several patterns require an array" "\n" 401 " match: [\"baz.*\",\"frob*\"]," "\n" 402 "" "\n" 403 " // only enable c1 for this directive" "\n" 404 " // all enabled by default. Command disables all not listed" "\n" 405 " enable: \"c1\"," "\n" 406 "" "\n" 407 " // applies to all compilers" "\n" 408 " // + force inline, - dont inline" "\n" 409 " inline : [ \"+java.util.*\", \"-com.sun.*\"]," "\n" 410 " print_inlining: true," "\n" 411 "" "\n" 412 " // force matching compiles to be blocking/syncronous" "\n" 413 " blocking_compile: true" "\n" 414 " }," "\n" 415 "]" "\n", true); 416 } 417 418 void JSON_GTest::log(uint indent, const char* format, ...) { 419 if (prev != JSON_KEY) { 420 for (uint i = 0; i < indent; i++) { 421 _st->print(" "); 422 } 423 } 424 va_list args; 425 va_start(args, format); 426 _st->vprint(format, args); 427 va_end(args); 428 } 429 430 bool JSON_GTest::callback(JSON_TYPE t, JSON_VAL* v, uint rlevel) { 431 switch (t) { 432 case JSON_OBJECT_BEGIN: 433 log(rlevel, "{\n"); 434 prev = JSON_NONE; // Only care about JSON_KEY, to indent correctly 435 return true; 436 437 case JSON_OBJECT_END: 438 log(rlevel, "},\n"); 439 prev = JSON_NONE; 440 return true; 441 442 case JSON_ARRAY_BEGIN: 443 log(rlevel, "[\n"); 444 prev = JSON_NONE; 445 return true; 446 447 case JSON_ARRAY_END: 448 log(rlevel, "],\n"); 449 prev = JSON_NONE; 450 return true; 451 452 case JSON_KEY: 453 for (uint i = 0; i < rlevel; i++) { 454 _st->print(" "); 455 } 456 _st->print("<key>"); 457 for (size_t i = 0; i < v->str.length; i++) { 458 u_char c = v->str.start[i]; 459 if (c == 0) { 460 return false; 461 } 462 _st->print("%c", c); 463 } 464 _st->print(" : "); 465 prev = JSON_KEY; 466 return true; 467 468 case JSON_STRING: 469 if (prev != JSON_KEY) { 470 for (uint i = 0; i < rlevel; i++) { 471 _st->print(" "); 472 } 473 } 474 _st->print("<str>"); 475 for (size_t i = 0; i < v->str.length; i++) { 476 u_char c = v->str.start[i]; 477 if (c == 0) { 478 return false; 479 } 480 _st->print("%c", c); 481 } 482 _st->print(",\n"); 483 prev = JSON_NONE; 484 return true; 485 486 case JSON_NUMBER_INT: 487 log(rlevel, "<int>%" PRId64 ",\n", v->int_value); 488 prev = JSON_NONE; 489 return true; 490 491 case JSON_NUMBER_FLOAT: 492 log(rlevel, "<double>%lf,\n", v->double_value); 493 prev = JSON_NONE; 494 return true; 495 496 case JSON_TRUE: 497 log(rlevel, "<true>,\n"); 498 prev = JSON_NONE; 499 return true; 500 501 case JSON_FALSE: 502 log(rlevel, "<false>,\n"); 503 prev = JSON_NONE; 504 return true; 505 506 case JSON_NULL: 507 log(rlevel, "<null>,\n"); 508 prev = JSON_NONE; 509 return true; 510 511 default: 512 error(INTERNAL_ERROR, "unknown JSON type"); 513 return false; 514 } 515 }