diff --git a/src/support/json.h b/src/support/json.h index c005543f60e..ac8143b0c7f 100644 --- a/src/support/json.h +++ b/src/support/json.h @@ -39,6 +39,7 @@ #include "support/istring.h" #include "support/safe_integer.h" +#include "support/utilities.h" namespace json { @@ -257,12 +258,22 @@ struct Value { while (*curr && is_json_space(*curr)) \ curr++; \ } +#define skip_escaped_characters(ptr) \ + while (*ptr && *ptr != '"') { \ + if (*ptr == '\\' && *(ptr + 1)) { \ + ptr++; \ + } \ + ptr++; \ + } skip(); if (*curr == '"') { // String curr++; - char* close = strchr(curr, '"'); - assert(close); + char* close = curr; + skip_escaped_characters(close); + if (!(*close == '"')) { + wasm::Fatal() << "Assertion failed (close == '\"') "; + } *close = 0; // end this string, and reuse it straight from the input setString(curr); curr = close + 1; @@ -305,20 +316,37 @@ struct Value { skip(); setObject(); while (*curr != '}') { - assert(*curr == '"'); - curr++; - char* close = strchr(curr, '"'); - assert(close); - *close = 0; // end this string, and reuse it straight from the input - IString key(curr); - curr = close + 1; - skip(); - assert(*curr == ':'); - curr++; - skip(); - Ref value = Ref(new Value()); - curr = value->parse(curr); - (*obj)[key] = value; + if (*curr == '"') { + curr++; + char* close = curr; + skip_escaped_characters(close); + if (!(*close == '"')) { + wasm::Fatal() << "Assertion failed (close == '\"') "; + } + *close = 0; // end this string, and reuse it straight from the input + IString key(curr); + curr = close + 1; + skip(); + assert(*curr == ':'); + curr++; + skip(); + Ref value = Ref(new Value()); + curr = value->parse(curr); + (*obj)[key] = value; + } else { + // Unquoted key + char* start = curr; + while (*curr && *curr != ':' && !is_json_space(*curr)) { + curr++; + } + assert(*curr == ':'); + IString key(std::string(start, curr - start).c_str()); + curr++; + skip(); + Ref value = Ref(new Value()); + curr = value->parse(curr); + (*obj)[key] = value; + } skip(); if (*curr == '}') { break; diff --git a/test/lit/metadce/functions_with_names_need_escape.wat b/test/lit/metadce/functions_with_names_need_escape.wat new file mode 100644 index 00000000000..bbdc736f465 --- /dev/null +++ b/test/lit/metadce/functions_with_names_need_escape.wat @@ -0,0 +1,8 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-metadce %s --graph-file %s.json -S -o - + +(module + (func $f (export "f") + (nop) + ) +) \ No newline at end of file diff --git a/test/lit/metadce/functions_with_names_need_escape.wat.json b/test/lit/metadce/functions_with_names_need_escape.wat.json new file mode 100644 index 00000000000..0d982a13d45 --- /dev/null +++ b/test/lit/metadce/functions_with_names_need_escape.wat.json @@ -0,0 +1,13 @@ +[ + { + "name": "root", + "reaches": [ + "f","f~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./" + ], + "root": true + }, + { + "name": "f", + "export": "f" + } +] \ No newline at end of file diff --git a/test/lit/metadce/keys_quoted_unquoted.wat b/test/lit/metadce/keys_quoted_unquoted.wat new file mode 100644 index 00000000000..bbdc736f465 --- /dev/null +++ b/test/lit/metadce/keys_quoted_unquoted.wat @@ -0,0 +1,8 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. +;; RUN: wasm-metadce %s --graph-file %s.json -S -o - + +(module + (func $f (export "f") + (nop) + ) +) \ No newline at end of file diff --git a/test/lit/metadce/keys_quoted_unquoted.wat.json b/test/lit/metadce/keys_quoted_unquoted.wat.json new file mode 100644 index 00000000000..dbc47a3bbcc --- /dev/null +++ b/test/lit/metadce/keys_quoted_unquoted.wat.json @@ -0,0 +1,13 @@ +[ + { + name: "root", + reaches: [ + "f" + ], + root: true + }, + { + "name": "f", + "export": "f" + } +]