diff --git a/Changelog.md b/Changelog.md index 0179f7524..99fed65c2 100644 --- a/Changelog.md +++ b/Changelog.md @@ -10,6 +10,11 @@ Compiler Features: Bugfixes: + * AST: Do not output value of Yul literal if it is not a valid UTF-8 string. + + +AST Changes: + * Add member `hexValue` for Yul string and hex literals. ### 0.8.4 (2021-04-21) diff --git a/libyul/AsmJsonConverter.cpp b/libyul/AsmJsonConverter.cpp index 582d95a82..fe595e7d2 100644 --- a/libyul/AsmJsonConverter.cpp +++ b/libyul/AsmJsonConverter.cpp @@ -24,6 +24,7 @@ #include #include #include +#include using namespace std; @@ -63,10 +64,12 @@ Json::Value AsmJsonConverter::operator()(Literal const& _node) const break; case LiteralKind::String: ret["kind"] = "string"; + ret["hexValue"] = util::toHex(util::asBytes(_node.value.str())); break; } ret["type"] = _node.type.str(); - ret["value"] = _node.value.str(); + if (util::validateUTF8(_node.value.str())) + ret["value"] = _node.value.str(); return ret; } diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index 410bdbed5..0aacbdf84 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -158,7 +158,12 @@ Literal AsmJsonImporter::createLiteral(Json::Value const& _node) auto lit = createAsmNode(_node); string kind = member(_node, "kind").asString(); - lit.value = YulString{member(_node, "value").asString()}; + solAssert(member(_node, "hexValue").isString() || member(_node, "value").isString(), ""); + if (_node.isMember("hexValue")) + lit.value = YulString{util::asString(util::fromHex(member(_node, "hexValue").asString()))}; + else + lit.value = YulString{member(_node, "value").asString()}; + lit.type= YulString{member(_node, "type").asString()}; if (kind == "number") diff --git a/test/libsolidity/ASTJSON/yul_hex_literal.json b/test/libsolidity/ASTJSON/yul_hex_literal.json new file mode 100644 index 000000000..54d37da00 --- /dev/null +++ b/test/libsolidity/ASTJSON/yul_hex_literal.json @@ -0,0 +1,154 @@ +{ + "absolutePath": "a", + "exportedSymbols": + { + "Sample": + [ + 6 + ] + }, + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 6, + "linearizedBaseContracts": + [ + 6 + ], + "name": "Sample", + "nameLocation": "9:6:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "47:167:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "66:142:1", + "statements": + [ + { + "nodeType": "YulVariableDeclaration", + "src": "80:15:1", + "value": + { + "hexValue": "74657374", + "kind": "string", + "nodeType": "YulLiteral", + "src": "89:6:1", + "type": "", + "value": "test" + }, + "variables": + [ + { + "name": "a", + "nodeType": "YulTypedName", + "src": "84:1:1", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "108:54:1", + "value": + { + "hexValue": "112233445566778899aabbccddeeff6677889900", + "kind": "string", + "nodeType": "YulLiteral", + "src": "117:45:1", + "type": "" + }, + "variables": + [ + { + "name": "b", + "nodeType": "YulTypedName", + "src": "112:1:1", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "175:23:1", + "value": + { + "hexValue": "1234abcd", + "kind": "string", + "nodeType": "YulLiteral", + "src": "184:14:1", + "type": "" + }, + "variables": + [ + { + "name": "c", + "nodeType": "YulTypedName", + "src": "179:1:1", + "type": "" + } + ] + } + ] + }, + "evmVersion": %EVMVERSION%, + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "57:151:1" + } + ] + }, + "functionSelector": "26121ff0", + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "31:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "32:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "47:0:1" + }, + "scope": 6, + "src": "22:192:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 7, + "src": "0:216:1", + "usedErrors": [] + } + ], + "src": "0:217:1" +} diff --git a/test/libsolidity/ASTJSON/yul_hex_literal.sol b/test/libsolidity/ASTJSON/yul_hex_literal.sol new file mode 100644 index 000000000..f441866c1 --- /dev/null +++ b/test/libsolidity/ASTJSON/yul_hex_literal.sol @@ -0,0 +1,11 @@ +contract Sample { + function f() public pure { + assembly { + let a := "test" + let b := hex"112233445566778899aabbccddeeff6677889900" + let c := hex"1234_abcd" + } + } +} + +// ---- diff --git a/test/libsolidity/ASTJSON/yul_hex_literal_parseOnly.json b/test/libsolidity/ASTJSON/yul_hex_literal_parseOnly.json new file mode 100644 index 000000000..a6da7e778 --- /dev/null +++ b/test/libsolidity/ASTJSON/yul_hex_literal_parseOnly.json @@ -0,0 +1,139 @@ +{ + "absolutePath": "a", + "id": 7, + "nodeType": "SourceUnit", + "nodes": + [ + { + "abstract": false, + "baseContracts": [], + "contractDependencies": [], + "contractKind": "contract", + "id": 6, + "name": "Sample", + "nameLocation": "9:6:1", + "nodeType": "ContractDefinition", + "nodes": + [ + { + "body": + { + "id": 4, + "nodeType": "Block", + "src": "47:167:1", + "statements": + [ + { + "AST": + { + "nodeType": "YulBlock", + "src": "66:142:1", + "statements": + [ + { + "nodeType": "YulVariableDeclaration", + "src": "80:15:1", + "value": + { + "hexValue": "74657374", + "kind": "string", + "nodeType": "YulLiteral", + "src": "89:6:1", + "type": "", + "value": "test" + }, + "variables": + [ + { + "name": "a", + "nodeType": "YulTypedName", + "src": "84:1:1", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "108:54:1", + "value": + { + "hexValue": "112233445566778899aabbccddeeff6677889900", + "kind": "string", + "nodeType": "YulLiteral", + "src": "117:45:1", + "type": "" + }, + "variables": + [ + { + "name": "b", + "nodeType": "YulTypedName", + "src": "112:1:1", + "type": "" + } + ] + }, + { + "nodeType": "YulVariableDeclaration", + "src": "175:23:1", + "value": + { + "hexValue": "1234abcd", + "kind": "string", + "nodeType": "YulLiteral", + "src": "184:14:1", + "type": "" + }, + "variables": + [ + { + "name": "c", + "nodeType": "YulTypedName", + "src": "179:1:1", + "type": "" + } + ] + } + ] + }, + "evmVersion": %EVMVERSION%, + "externalReferences": [], + "id": 3, + "nodeType": "InlineAssembly", + "src": "57:151:1" + } + ] + }, + "id": 5, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "f", + "nameLocation": "31:1:1", + "nodeType": "FunctionDefinition", + "parameters": + { + "id": 1, + "nodeType": "ParameterList", + "parameters": [], + "src": "32:2:1" + }, + "returnParameters": + { + "id": 2, + "nodeType": "ParameterList", + "parameters": [], + "src": "47:0:1" + }, + "src": "22:192:1", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "src": "0:216:1", + "usedErrors": [] + } + ], + "src": "0:217:1" +}