From f756843d60caadb6f4994bbfb6f8925089b3d549 Mon Sep 17 00:00:00 2001 From: mtb0x1 Date: Thu, 26 Dec 2024 16:45:48 +0100 Subject: [PATCH 1/5] json.h update : - enable quoted and unquoted keys - skip escaped chars (cause of early parse abort) --- src/support/json.h | 58 +++++++++++++++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/src/support/json.h b/src/support/json.h index c005543f60e..8bac3f545e0 100644 --- a/src/support/json.h +++ b/src/support/json.h @@ -261,8 +261,14 @@ struct Value { if (*curr == '"') { // String curr++; - char* close = strchr(curr, '"'); - assert(close); + char* close = curr; + while (*close && *close != '"') { + if (*close == '\\' && *(close + 1)) { + close++; // Skip escaped character + } + close++; + } + assert(*close == '"'); *close = 0; // end this string, and reuse it straight from the input setString(curr); curr = close + 1; @@ -305,20 +311,40 @@ 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; + while (*close && *close != '"') { + if (*close == '\\' && *(close + 1)) { + close++; // Skip escaped character + } + close++; + } + 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; + } 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; From b85075fa6e9f8435dce108b522664b797253404e Mon Sep 17 00:00:00 2001 From: mtb0x1 Date: Mon, 30 Dec 2024 22:27:23 +0100 Subject: [PATCH 2/5] refactor --- src/support/json.h | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/support/json.h b/src/support/json.h index 8bac3f545e0..285afb2b015 100644 --- a/src/support/json.h +++ b/src/support/json.h @@ -257,18 +257,25 @@ struct Value { while (*curr && is_json_space(*curr)) \ curr++; \ } +#define skip_escaped_characters(ptr)\ + while (*ptr && *ptr != '"') {\ + if (*ptr == '\\' && *(ptr + 1)) {\ + ptr++;\ + }\ + ptr++;\ + } +#define RUNTIME_ASSERT(condition)\ + if (!(condition)) {\ + std::cerr << "Assertion failed: " #condition << " at " << __FILE__ << ":" << __LINE__ << "\n";\ + std::terminate();\ + } skip(); if (*curr == '"') { // String curr++; char* close = curr; - while (*close && *close != '"') { - if (*close == '\\' && *(close + 1)) { - close++; // Skip escaped character - } - close++; - } - assert(*close == '"'); + skip_escaped_characters(close); + RUNTIME_ASSERT(*close == '"'); *close = 0; // end this string, and reuse it straight from the input setString(curr); curr = close + 1; @@ -314,13 +321,8 @@ struct Value { if (*curr == '"') { curr++; char* close = curr; - while (*close && *close != '"') { - if (*close == '\\' && *(close + 1)) { - close++; // Skip escaped character - } - close++; - } - assert(*close == '"'); + skip_escaped_characters(close); + RUNTIME_ASSERT(*close == '"'); *close = 0; // end this string, and reuse it straight from the input IString key(curr); curr = close + 1; From a663593caef6ed6f76d30298c2424192989cf49e Mon Sep 17 00:00:00 2001 From: mtb0x1 Date: Mon, 30 Dec 2024 22:28:30 +0100 Subject: [PATCH 3/5] lint and tests --- src/support/json.h | 23 +++++++------ .../functions_with_names_need_escape.wat | 34 +++++++++++++++++++ .../functions_with_names_need_escape.wat.json | 13 +++++++ test/lit/metadce/keys_quoted_unquoted.wat | 34 +++++++++++++++++++ .../lit/metadce/keys_quoted_unquoted.wat.json | 13 +++++++ 5 files changed, 106 insertions(+), 11 deletions(-) create mode 100644 test/lit/metadce/functions_with_names_need_escape.wat create mode 100644 test/lit/metadce/functions_with_names_need_escape.wat.json create mode 100644 test/lit/metadce/keys_quoted_unquoted.wat create mode 100644 test/lit/metadce/keys_quoted_unquoted.wat.json diff --git a/src/support/json.h b/src/support/json.h index 285afb2b015..29152d566bc 100644 --- a/src/support/json.h +++ b/src/support/json.h @@ -257,17 +257,18 @@ struct Value { while (*curr && is_json_space(*curr)) \ curr++; \ } -#define skip_escaped_characters(ptr)\ - while (*ptr && *ptr != '"') {\ - if (*ptr == '\\' && *(ptr + 1)) {\ - ptr++;\ - }\ - ptr++;\ - } -#define RUNTIME_ASSERT(condition)\ - if (!(condition)) {\ - std::cerr << "Assertion failed: " #condition << " at " << __FILE__ << ":" << __LINE__ << "\n";\ - std::terminate();\ +#define skip_escaped_characters(ptr) \ + while (*ptr && *ptr != '"') { \ + if (*ptr == '\\' && *(ptr + 1)) { \ + ptr++; \ + } \ + ptr++; \ + } +#define RUNTIME_ASSERT(condition) \ + if (!(condition)) { \ + std::cerr << "Assertion failed: " #condition << " at " << __FILE__ << ":" \ + << __LINE__ << "\n"; \ + std::terminate(); \ } skip(); if (*curr == '"') { 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..eb863698d36 --- /dev/null +++ b/test/lit/metadce/functions_with_names_need_escape.wat @@ -0,0 +1,34 @@ +;; 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 - | filecheck %s --check-prefix=TXT +;; RUN: wasm-as %s -o %t.wasm --source-map %t.map +;; RUN: wasm-metadce %t.wasm --input-source-map %t.map --graph-file %s.json -o %t.out.wasm --output-source-map %t.out.map +;; RUN: wasm-dis %t.out.wasm --source-map %t.out.map -o - | filecheck %s --check-prefix=BIN + +;; Test that sourcemap information is preserved + +(module + ;;@ a:1:2 + ;; TXT: (type $0 (func)) + + ;; TXT: (export "f~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./" (func $f)) + + ;; TXT: (func $f + ;; TXT-NEXT: ;;@ a:7:8:someSymbol + ;; TXT-NEXT: (nop) + ;; TXT-NEXT: ;;@ a:9:10 + ;; TXT-NEXT: ) + (func $f (export "f~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./") + ;;@ a:7:8:someSymbol + (nop) + ;;@ a:9:10 + ) +) +;; BIN: (type $0 (func)) + +;; BIN: (export "f" (func $0)) + +;; BIN: (func $0 +;; BIN-NEXT: ;;@ a:7:8:someSymbol +;; BIN-NEXT: (nop) +;; BIN-NEXT: ;;@ a:9:10 +;; BIN-NEXT: ) 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..5e6762516e2 --- /dev/null +++ b/test/lit/metadce/functions_with_names_need_escape.wat.json @@ -0,0 +1,13 @@ +[ + { + "name": "root", + "reaches": [ + "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..0190fe557da --- /dev/null +++ b/test/lit/metadce/keys_quoted_unquoted.wat @@ -0,0 +1,34 @@ +;; 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 - | filecheck %s --check-prefix=TXT +;; RUN: wasm-as %s -o %t.wasm --source-map %t.map +;; RUN: wasm-metadce %t.wasm --input-source-map %t.map --graph-file %s.json -o %t.out.wasm --output-source-map %t.out.map +;; RUN: wasm-dis %t.out.wasm --source-map %t.out.map -o - | filecheck %s --check-prefix=BIN + +;; Test that sourcemap information is preserved + +(module + ;;@ a:1:2 + ;; TXT: (type $0 (func)) + + ;; TXT: (export "f" (func $f)) + + ;; TXT: (func $f + ;; TXT-NEXT: ;;@ a:7:8:someSymbol + ;; TXT-NEXT: (nop) + ;; TXT-NEXT: ;;@ a:9:10 + ;; TXT-NEXT: ) + (func $f (export "f") + ;;@ a:7:8:someSymbol + (nop) + ;;@ a:9:10 + ) +) +;; BIN: (type $0 (func)) + +;; BIN: (export "f" (func $0)) + +;; BIN: (func $0 +;; BIN-NEXT: ;;@ a:7:8:someSymbol +;; BIN-NEXT: (nop) +;; BIN-NEXT: ;;@ a:9:10 +;; BIN-NEXT: ) 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" + } +] From 800fb82f0771fc4fd842af68926f1077bda84599 Mon Sep 17 00:00:00 2001 From: mtb0x1 Date: Mon, 30 Dec 2024 22:57:21 +0100 Subject: [PATCH 4/5] fix test --- test/lit/metadce/functions_with_names_need_escape.wat | 4 ++-- test/lit/metadce/functions_with_names_need_escape.wat.json | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/test/lit/metadce/functions_with_names_need_escape.wat b/test/lit/metadce/functions_with_names_need_escape.wat index eb863698d36..0190fe557da 100644 --- a/test/lit/metadce/functions_with_names_need_escape.wat +++ b/test/lit/metadce/functions_with_names_need_escape.wat @@ -10,14 +10,14 @@ ;;@ a:1:2 ;; TXT: (type $0 (func)) - ;; TXT: (export "f~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./" (func $f)) + ;; TXT: (export "f" (func $f)) ;; TXT: (func $f ;; TXT-NEXT: ;;@ a:7:8:someSymbol ;; TXT-NEXT: (nop) ;; TXT-NEXT: ;;@ a:9:10 ;; TXT-NEXT: ) - (func $f (export "f~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./") + (func $f (export "f") ;;@ a:7:8:someSymbol (nop) ;;@ a:9:10 diff --git a/test/lit/metadce/functions_with_names_need_escape.wat.json b/test/lit/metadce/functions_with_names_need_escape.wat.json index 5e6762516e2..0d982a13d45 100644 --- a/test/lit/metadce/functions_with_names_need_escape.wat.json +++ b/test/lit/metadce/functions_with_names_need_escape.wat.json @@ -2,12 +2,12 @@ { "name": "root", "reaches": [ - "f~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./" + "f","f~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./" ], "root": true }, { - "name": "f~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./", - "export": "f~!@#$%^&*()_+`-={}|[]\\:\";'<>?,./" + "name": "f", + "export": "f" } ] \ No newline at end of file From 5e07222c40c8a939ae7f989859bf8ee274ea44ca Mon Sep 17 00:00:00 2001 From: mtb0x1 Date: Mon, 30 Dec 2024 23:42:16 +0100 Subject: [PATCH 5/5] cleanup --- src/support/json.h | 15 +++++----- .../functions_with_names_need_escape.wat | 30 ++----------------- test/lit/metadce/keys_quoted_unquoted.wat | 30 ++----------------- 3 files changed, 11 insertions(+), 64 deletions(-) diff --git a/src/support/json.h b/src/support/json.h index 29152d566bc..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 { @@ -264,19 +265,15 @@ struct Value { } \ ptr++; \ } -#define RUNTIME_ASSERT(condition) \ - if (!(condition)) { \ - std::cerr << "Assertion failed: " #condition << " at " << __FILE__ << ":" \ - << __LINE__ << "\n"; \ - std::terminate(); \ - } skip(); if (*curr == '"') { // String curr++; char* close = curr; skip_escaped_characters(close); - RUNTIME_ASSERT(*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; @@ -323,7 +320,9 @@ struct Value { curr++; char* close = curr; skip_escaped_characters(close); - RUNTIME_ASSERT(*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; diff --git a/test/lit/metadce/functions_with_names_need_escape.wat b/test/lit/metadce/functions_with_names_need_escape.wat index 0190fe557da..bbdc736f465 100644 --- a/test/lit/metadce/functions_with_names_need_escape.wat +++ b/test/lit/metadce/functions_with_names_need_escape.wat @@ -1,34 +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 - | filecheck %s --check-prefix=TXT -;; RUN: wasm-as %s -o %t.wasm --source-map %t.map -;; RUN: wasm-metadce %t.wasm --input-source-map %t.map --graph-file %s.json -o %t.out.wasm --output-source-map %t.out.map -;; RUN: wasm-dis %t.out.wasm --source-map %t.out.map -o - | filecheck %s --check-prefix=BIN - -;; Test that sourcemap information is preserved +;; RUN: wasm-metadce %s --graph-file %s.json -S -o - (module - ;;@ a:1:2 - ;; TXT: (type $0 (func)) - - ;; TXT: (export "f" (func $f)) - - ;; TXT: (func $f - ;; TXT-NEXT: ;;@ a:7:8:someSymbol - ;; TXT-NEXT: (nop) - ;; TXT-NEXT: ;;@ a:9:10 - ;; TXT-NEXT: ) (func $f (export "f") - ;;@ a:7:8:someSymbol (nop) - ;;@ a:9:10 ) -) -;; BIN: (type $0 (func)) - -;; BIN: (export "f" (func $0)) - -;; BIN: (func $0 -;; BIN-NEXT: ;;@ a:7:8:someSymbol -;; BIN-NEXT: (nop) -;; BIN-NEXT: ;;@ a:9:10 -;; BIN-NEXT: ) +) \ No newline at end of file diff --git a/test/lit/metadce/keys_quoted_unquoted.wat b/test/lit/metadce/keys_quoted_unquoted.wat index 0190fe557da..bbdc736f465 100644 --- a/test/lit/metadce/keys_quoted_unquoted.wat +++ b/test/lit/metadce/keys_quoted_unquoted.wat @@ -1,34 +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 - | filecheck %s --check-prefix=TXT -;; RUN: wasm-as %s -o %t.wasm --source-map %t.map -;; RUN: wasm-metadce %t.wasm --input-source-map %t.map --graph-file %s.json -o %t.out.wasm --output-source-map %t.out.map -;; RUN: wasm-dis %t.out.wasm --source-map %t.out.map -o - | filecheck %s --check-prefix=BIN - -;; Test that sourcemap information is preserved +;; RUN: wasm-metadce %s --graph-file %s.json -S -o - (module - ;;@ a:1:2 - ;; TXT: (type $0 (func)) - - ;; TXT: (export "f" (func $f)) - - ;; TXT: (func $f - ;; TXT-NEXT: ;;@ a:7:8:someSymbol - ;; TXT-NEXT: (nop) - ;; TXT-NEXT: ;;@ a:9:10 - ;; TXT-NEXT: ) (func $f (export "f") - ;;@ a:7:8:someSymbol (nop) - ;;@ a:9:10 ) -) -;; BIN: (type $0 (func)) - -;; BIN: (export "f" (func $0)) - -;; BIN: (func $0 -;; BIN-NEXT: ;;@ a:7:8:someSymbol -;; BIN-NEXT: (nop) -;; BIN-NEXT: ;;@ a:9:10 -;; BIN-NEXT: ) +) \ No newline at end of file