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 }