From 12dbf44592a876c109d06a65976b705cf6da4026 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Thu, 6 Aug 2026 06:19:14 +0300 Subject: [PATCH] AsmJsonImporter: Replace validation asserts with proper AstImportError The importer runs on untrusted JSON input but used yulAssert/solAssert for input validation. Failures surfaced as `type: "Exception"`, which the documentation defines as an internal bug to be reported. - Introduce langutil::AstImportError and throw it via solRequire()/ solThrow() for all malformed-input conditions in AsmJsonImporter. - Validate string fields accessed through nlohmann (name, kind, hexValue, value) instead of letting raw type_errors escape. - Catch the new type in StandardCompiler and report it as `type: "JSONError"`, keeping the "Failed to import AST: " prefix. - Cover the failure paths with standard-json cmdline tests. Partially addresses #15854 (the AsmJsonImporter half). --- Changelog.md | 1 + liblangutil/Exceptions.h | 1 + libsolidity/interface/StandardCompiler.cpp | 15 ++ libyul/AsmJsonImporter.cpp | 76 +++--- libyul/AsmJsonImporter.h | 7 +- .../input.json | 222 ++++++++++++++++++ .../output.json | 14 ++ .../input.json | 222 ++++++++++++++++++ .../output.json | 14 ++ .../input.json | 221 +++++++++++++++++ .../output.json | 14 ++ .../input.json | 222 ++++++++++++++++++ .../output.json | 14 ++ 13 files changed, 1009 insertions(+), 34 deletions(-) create mode 100644 test/cmdlineTests/standard_import_ast_invalid_yul_statement_prefix/input.json create mode 100644 test/cmdlineTests/standard_import_ast_invalid_yul_statement_prefix/output.json create mode 100644 test/cmdlineTests/standard_import_ast_unknown_yul_statement/input.json create mode 100644 test/cmdlineTests/standard_import_ast_unknown_yul_statement/output.json create mode 100644 test/cmdlineTests/standard_import_ast_yul_identifier_missing_name/input.json create mode 100644 test/cmdlineTests/standard_import_ast_yul_identifier_missing_name/output.json create mode 100644 test/cmdlineTests/standard_import_ast_yul_src_not_string/input.json create mode 100644 test/cmdlineTests/standard_import_ast_yul_src_not_string/output.json diff --git a/Changelog.md b/Changelog.md index b496b7c5bba8..50fd15a06238 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ Compiler Features: Bugfixes: * Code Generator: Fix ICE on parenthesized custom error construction in require statement. * Commandline Interface: Report proper error instead of ICE on non-hex mixed-case address value given via `--libraries`. +* Standard JSON Interface: Malformed inline assembly in an AST supplied via the `SolidityAST` input is now reported as a `JSONError` instead of an internal `Exception`. Build System: * Update minimum version requirement of Boost to 1.83.0 for Windows build. This matches the minimum version for other systems. diff --git a/liblangutil/Exceptions.h b/liblangutil/Exceptions.h index 2f2fdcb4c997..e79dec4e7c06 100644 --- a/liblangutil/Exceptions.h +++ b/liblangutil/Exceptions.h @@ -50,6 +50,7 @@ struct InternalCompilerError: virtual util::Exception {}; struct FatalError: virtual util::Exception {}; struct UnimplementedFeatureError: virtual util::Exception {}; struct InvalidAstError: virtual util::Exception {}; +struct AstImportError: virtual util::Exception {}; /// Assertion that throws an InternalCompilerError containing the given description if it is not met. diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index c8cb87504624..ac999f139d00 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1482,6 +1482,11 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu if (binariesRequested) compilerStack.compile(); } + catch (AstImportError const&) + { + // Rethrow to let the outer handler classify it as a JSONError. + throw; + } catch (util::Exception const& _exc) { solThrow(util::Exception, "Failed to import AST: "s + _exc.what()); @@ -1526,6 +1531,16 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu "" // No prefix needed. These messages already say it's a "stack too deep" error. )); } + catch (AstImportError const& _exception) + { + errors.emplace_back(formatErrorWithException( + compilerStack, + _exception, + Error::Type::JSONError, + "general", + "Failed to import AST" + )); + } catch (InternalCompilerError const&) { errors.emplace_back(formatError( diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index a937be62fb7a..7dd097b1e24d 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -32,6 +32,10 @@ #include #include +#include + +#include + #include #include @@ -46,7 +50,7 @@ using SourceLocation = langutil::SourceLocation; SourceLocation const AsmJsonImporter::createSourceLocation(Json const& _node) { - yulAssert(member(_node, "src").is_string(), "'src' must be a string"); + solRequire(member(_node, "src").is_string(), AstImportError, "'src' must be a string"); return solidity::langutil::parseSourceLocation(_node["src"].get(), m_sourceNames); } @@ -61,7 +65,7 @@ T AsmJsonImporter::createAsmNode(Json const& _node) { T r; SourceLocation nativeLocation = createSourceLocation(_node); - yulAssert(nativeLocation.hasText(), "Invalid source location in Asm AST"); + solRequire(nativeLocation.hasText(), AstImportError, "Invalid source location in Asm AST"); // TODO: We should add originLocation to the AST. // While it's not included, we'll use nativeLocation for it because we only support importing // inline assembly as a part of a Solidity AST and there these locations are always the same. @@ -76,20 +80,24 @@ Json AsmJsonImporter::member(Json const& _node, std::string const& _name) return _node[_name]; } +std::string AsmJsonImporter::requiredString(Json const& _node, std::string const& _name) +{ + Json const value = member(_node, _name); + solRequire(value.is_string(), AstImportError, fmt::format("Expected \"{}\" to be a string.", _name)); + return value.get(); +} + NameWithDebugData AsmJsonImporter::createNameWithDebugData(Json const& _node) { auto nameWithDebugData = createAsmNode(_node); - nameWithDebugData.name = YulName{member(_node, "name").get()}; + nameWithDebugData.name = YulName{requiredString(_node, "name")}; return nameWithDebugData; } Statement AsmJsonImporter::createStatement(Json const& _node) { - Json jsonNodeType = member(_node, "nodeType"); - yulAssert(jsonNodeType.is_string(), "Expected \"nodeType\" to be of type string!"); - std::string nodeType = jsonNodeType.get(); - - yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix"); + std::string nodeType = requiredString(_node, "nodeType"); + solRequire(nodeType.substr(0, 3) == "Yul", AstImportError, "Invalid nodeType prefix"); nodeType = nodeType.substr(3); if (nodeType == "ExpressionStatement") @@ -115,7 +123,7 @@ Statement AsmJsonImporter::createStatement(Json const& _node) else if (nodeType == "Block") return createBlock(_node); else - yulAssert(false, "Invalid nodeType as statement"); + solThrow(AstImportError, "Invalid nodeType as statement"); // FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794) util::unreachable(); @@ -123,11 +131,8 @@ Statement AsmJsonImporter::createStatement(Json const& _node) Expression AsmJsonImporter::createExpression(Json const& _node) { - Json jsonNodeType = member(_node, "nodeType"); - yulAssert(jsonNodeType.is_string(), "Expected \"nodeType\" to be of type string!"); - std::string nodeType = jsonNodeType.get(); - - yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix"); + std::string nodeType = requiredString(_node, "nodeType"); + solRequire(nodeType.substr(0, 3) == "Yul", AstImportError, "Invalid nodeType prefix"); nodeType = nodeType.substr(3); if (nodeType == "FunctionCall") @@ -137,7 +142,7 @@ Expression AsmJsonImporter::createExpression(Json const& _node) else if (nodeType == "Literal") return createLiteral(_node); else - yulAssert(false, "Invalid nodeType as expression"); + solThrow(AstImportError, "Invalid nodeType as expression"); // FIXME: Workaround for spurious GCC 12.1 warning (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105794) util::unreachable(); @@ -169,21 +174,21 @@ Block AsmJsonImporter::createBlock(Json const& _node) Literal AsmJsonImporter::createLiteral(Json const& _node) { auto lit = createAsmNode(_node); - std::string kind = member(_node, "kind").get(); + std::string kind = requiredString(_node, "kind"); - solAssert(member(_node, "hexValue").is_string() || member(_node, "value").is_string(), ""); std::string value; if (_node.contains("hexValue")) - value = util::asString(util::fromHex(member(_node, "hexValue").get())); + value = util::asString(util::fromHex(requiredString(_node, "hexValue"))); else - value = member(_node, "value").get(); + value = requiredString(_node, "value"); { auto const typeNode = member(_node, "type"); - yulAssert( - typeNode.empty() || typeNode.get().empty(), + solRequire( + typeNode.empty() || (typeNode.is_string() && typeNode.get().empty()), + AstImportError, fmt::format( - "Expected literal types to be either empty or absent in the JSON. Got \"{}\".", - typeNode.get() + "Expected literal types to be either empty or absent in the JSON. Got {}.", + typeNode.dump() ) ); } @@ -192,8 +197,9 @@ Literal AsmJsonImporter::createLiteral(Json const& _node) langutil::CharStream charStream(value, ""); langutil::Scanner scanner{charStream}; lit.kind = LiteralKind::Number; - yulAssert( + solRequire( scanner.currentToken() == Token::Number, + AstImportError, "Expected number but got " + langutil::TokenTraits::friendlyName(scanner.currentToken()) + std::string(" while scanning ") + value ); } @@ -202,27 +208,29 @@ Literal AsmJsonImporter::createLiteral(Json const& _node) langutil::CharStream charStream(value, ""); langutil::Scanner scanner{charStream}; lit.kind = LiteralKind::Boolean; - yulAssert( + solRequire( scanner.currentToken() == Token::TrueLiteral || scanner.currentToken() == Token::FalseLiteral, + AstImportError, "Expected true/false literal!" ); } else if (kind == "string") { lit.kind = LiteralKind::String; - yulAssert( + solRequire( value.size() <= 32, + AstImportError, "String literal too long (" + std::to_string(value.size()) + " > 32)" ); } else - yulAssert(false, "unknown type of literal"); + solThrow(AstImportError, "unknown type of literal"); // import only for inline assembly, no unlimited string literals there lit.value = valueOfLiteral(value, lit.kind, false /* _unlimitedLiteralArgument */); - yulAssert(validLiteral(lit)); + solRequire(validLiteral(lit), AstImportError, "Invalid literal value."); return lit; } @@ -234,7 +242,7 @@ Leave AsmJsonImporter::createLeave(Json const& _node) Identifier AsmJsonImporter::createIdentifier(Json const& _node) { auto identifier = createAsmNode(_node); - identifier.name = YulName(member(_node, "name").get()); + identifier.name = YulName(requiredString(_node, "name")); return identifier; } @@ -258,7 +266,7 @@ FunctionCall AsmJsonImporter::createFunctionCall(Json const& _node) functionCall.arguments.emplace_back(createExpression(var)); auto const functionNameNode = member(_node, "functionName"); - auto const name = member(functionNameNode, "name").get(); + auto const name = requiredString(functionNameNode, "name"); if (std::optional builtinHandle = m_dialect.findBuiltin(name)) { auto builtin = createAsmNode(functionNameNode); @@ -293,7 +301,7 @@ VariableDeclaration AsmJsonImporter::createVariableDeclaration(Json const& _node FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json const& _node) { auto funcDef = createAsmNode(_node); - funcDef.name = YulName{member(_node, "name").get()}; + funcDef.name = YulName{requiredString(_node, "name")}; if (_node.contains("parameters")) for (auto const& var: member(_node, "parameters")) @@ -320,7 +328,11 @@ Case AsmJsonImporter::createCase(Json const& _node) auto caseStatement = createAsmNode(_node); auto const& value = member(_node, "value"); if (value.is_string()) - yulAssert(value.get() == "default", "Expected default case"); + { + // NOTE: The braces are essential. solRequire() expands to an if statement and would + // otherwise steal the else branch below. + solRequire(value.get() == "default", AstImportError, "Expected default case"); + } else caseStatement.value = std::make_unique(createLiteral(value)); caseStatement.body = createBlock(member(_node, "body")); diff --git a/libyul/AsmJsonImporter.h b/libyul/AsmJsonImporter.h index 830e44b3acb1..e612bb974a21 100644 --- a/libyul/AsmJsonImporter.h +++ b/libyul/AsmJsonImporter.h @@ -50,9 +50,12 @@ class AsmJsonImporter langutil::SourceLocation const createSourceLocation(Json const& _node); template T createAsmNode(Json const& _node); - /// helper function to access member functions of the JSON - /// and throw an error if it does not exist + /// helper function to access a member of the JSON node; + /// returns a null value if the member does not exist Json member(Json const& _node, std::string const& _name); + /// Retrieves the value of the given member of a JSON node. + /// Throws AstImportError if the member is missing or not a string. + std::string requiredString(Json const& _node, std::string const& _name); yul::Block createBlock(Json const& _node); yul::Statement createStatement(Json const& _node); diff --git a/test/cmdlineTests/standard_import_ast_invalid_yul_statement_prefix/input.json b/test/cmdlineTests/standard_import_ast_invalid_yul_statement_prefix/input.json new file mode 100644 index 000000000000..92467481a735 --- /dev/null +++ b/test/cmdlineTests/standard_import_ast_invalid_yul_statement_prefix/input.json @@ -0,0 +1,222 @@ +{ + "language": "SolidityAST", + "sources": { + "A": { + "ast": { + "absolutePath": "A", + "exportedSymbols": { + "AsmTest": [ + 11 + ] + }, + "id": 12, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "36:22:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "AsmTest", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 11, + "linearizedBaseContracts": [ + 11 + ], + "name": "AsmTest", + "nameLocation": "68:7:0", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 9, + "nodeType": "Block", + "src": "134:31:0", + "statements": [ + { + "AST": { + "nativeSrc": "145:18:0", + "nodeType": "YulBlock", + "src": "145:18:0", + "statements": [ + { + "nativeSrc": "147:14:0", + "nodeType": "XulAssignment", + "src": "147:14:0", + "value": { + "arguments": [ + { + "name": "x", + "nativeSrc": "156:1:0", + "nodeType": "YulIdentifier", + "src": "156:1:0" + }, + { + "kind": "number", + "nativeSrc": "159:1:0", + "nodeType": "YulLiteral", + "src": "159:1:0", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "152:3:0", + "nodeType": "YulIdentifier", + "src": "152:3:0" + }, + "nativeSrc": "152:9:0", + "nodeType": "YulFunctionCall", + "src": "152:9:0" + }, + "variableNames": [ + { + "name": "y", + "nativeSrc": "147:1:0", + "nodeType": "YulIdentifier", + "src": "147:1:0" + } + ] + } + ] + }, + "evmVersion": "cancun", + "externalReferences": [ + { + "declaration": 3, + "isOffset": false, + "isSlot": false, + "src": "156:1:0", + "valueSize": 1 + }, + { + "declaration": 6, + "isOffset": false, + "isSlot": false, + "src": "147:1:0", + "valueSize": 1 + } + ], + "id": 8, + "nodeType": "InlineAssembly", + "src": "136:27:0" + } + ] + }, + "functionSelector": "2fbebd38", + "id": 10, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "foo", + "nameLocation": "87:3:0", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 4, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 3, + "mutability": "mutable", + "name": "x", + "nameLocation": "99:1:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "91:9:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "91:7:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "90:11:0" + }, + "returnParameters": { + "id": 7, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "y", + "nameLocation": "131:1:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "123:9:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 5, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "123:7:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "122:11:0" + }, + "scope": 11, + "src": "78:87:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 12, + "src": "59:108:0", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "36:131:0" + } + } + }, + "settings": { + "experimental": true, + "evmVersion": "cancun", + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.object" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_import_ast_invalid_yul_statement_prefix/output.json b/test/cmdlineTests/standard_import_ast_invalid_yul_statement_prefix/output.json new file mode 100644 index 000000000000..7ca304549f06 --- /dev/null +++ b/test/cmdlineTests/standard_import_ast_invalid_yul_statement_prefix/output.json @@ -0,0 +1,14 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "JSONError: Invalid nodeType prefix + +", + "message": "Failed to import AST: Invalid nodeType prefix", + "severity": "error", + "type": "JSONError" + } + ], + "sources": {} +} diff --git a/test/cmdlineTests/standard_import_ast_unknown_yul_statement/input.json b/test/cmdlineTests/standard_import_ast_unknown_yul_statement/input.json new file mode 100644 index 000000000000..ad6ebb310d7d --- /dev/null +++ b/test/cmdlineTests/standard_import_ast_unknown_yul_statement/input.json @@ -0,0 +1,222 @@ +{ + "language": "SolidityAST", + "sources": { + "A": { + "ast": { + "absolutePath": "A", + "exportedSymbols": { + "AsmTest": [ + 11 + ] + }, + "id": 12, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "36:22:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "AsmTest", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 11, + "linearizedBaseContracts": [ + 11 + ], + "name": "AsmTest", + "nameLocation": "68:7:0", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 9, + "nodeType": "Block", + "src": "134:31:0", + "statements": [ + { + "AST": { + "nativeSrc": "145:18:0", + "nodeType": "YulBlock", + "src": "145:18:0", + "statements": [ + { + "nativeSrc": "147:14:0", + "nodeType": "YulTotallyUnknownThing", + "src": "147:14:0", + "value": { + "arguments": [ + { + "name": "x", + "nativeSrc": "156:1:0", + "nodeType": "YulIdentifier", + "src": "156:1:0" + }, + { + "kind": "number", + "nativeSrc": "159:1:0", + "nodeType": "YulLiteral", + "src": "159:1:0", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "152:3:0", + "nodeType": "YulIdentifier", + "src": "152:3:0" + }, + "nativeSrc": "152:9:0", + "nodeType": "YulFunctionCall", + "src": "152:9:0" + }, + "variableNames": [ + { + "name": "y", + "nativeSrc": "147:1:0", + "nodeType": "YulIdentifier", + "src": "147:1:0" + } + ] + } + ] + }, + "evmVersion": "cancun", + "externalReferences": [ + { + "declaration": 3, + "isOffset": false, + "isSlot": false, + "src": "156:1:0", + "valueSize": 1 + }, + { + "declaration": 6, + "isOffset": false, + "isSlot": false, + "src": "147:1:0", + "valueSize": 1 + } + ], + "id": 8, + "nodeType": "InlineAssembly", + "src": "136:27:0" + } + ] + }, + "functionSelector": "2fbebd38", + "id": 10, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "foo", + "nameLocation": "87:3:0", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 4, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 3, + "mutability": "mutable", + "name": "x", + "nameLocation": "99:1:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "91:9:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "91:7:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "90:11:0" + }, + "returnParameters": { + "id": 7, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "y", + "nameLocation": "131:1:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "123:9:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 5, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "123:7:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "122:11:0" + }, + "scope": 11, + "src": "78:87:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 12, + "src": "59:108:0", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "36:131:0" + } + } + }, + "settings": { + "experimental": true, + "evmVersion": "cancun", + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.object" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_import_ast_unknown_yul_statement/output.json b/test/cmdlineTests/standard_import_ast_unknown_yul_statement/output.json new file mode 100644 index 000000000000..8b8f56ced93d --- /dev/null +++ b/test/cmdlineTests/standard_import_ast_unknown_yul_statement/output.json @@ -0,0 +1,14 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "JSONError: Invalid nodeType as statement + +", + "message": "Failed to import AST: Invalid nodeType as statement", + "severity": "error", + "type": "JSONError" + } + ], + "sources": {} +} diff --git a/test/cmdlineTests/standard_import_ast_yul_identifier_missing_name/input.json b/test/cmdlineTests/standard_import_ast_yul_identifier_missing_name/input.json new file mode 100644 index 000000000000..51300c658519 --- /dev/null +++ b/test/cmdlineTests/standard_import_ast_yul_identifier_missing_name/input.json @@ -0,0 +1,221 @@ +{ + "language": "SolidityAST", + "sources": { + "A": { + "ast": { + "absolutePath": "A", + "exportedSymbols": { + "AsmTest": [ + 11 + ] + }, + "id": 12, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "36:22:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "AsmTest", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 11, + "linearizedBaseContracts": [ + 11 + ], + "name": "AsmTest", + "nameLocation": "68:7:0", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 9, + "nodeType": "Block", + "src": "134:31:0", + "statements": [ + { + "AST": { + "nativeSrc": "145:18:0", + "nodeType": "YulBlock", + "src": "145:18:0", + "statements": [ + { + "nativeSrc": "147:14:0", + "nodeType": "YulAssignment", + "src": "147:14:0", + "value": { + "arguments": [ + { + "nativeSrc": "156:1:0", + "nodeType": "YulIdentifier", + "src": "156:1:0" + }, + { + "kind": "number", + "nativeSrc": "159:1:0", + "nodeType": "YulLiteral", + "src": "159:1:0", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "152:3:0", + "nodeType": "YulIdentifier", + "src": "152:3:0" + }, + "nativeSrc": "152:9:0", + "nodeType": "YulFunctionCall", + "src": "152:9:0" + }, + "variableNames": [ + { + "name": "y", + "nativeSrc": "147:1:0", + "nodeType": "YulIdentifier", + "src": "147:1:0" + } + ] + } + ] + }, + "evmVersion": "cancun", + "externalReferences": [ + { + "declaration": 3, + "isOffset": false, + "isSlot": false, + "src": "156:1:0", + "valueSize": 1 + }, + { + "declaration": 6, + "isOffset": false, + "isSlot": false, + "src": "147:1:0", + "valueSize": 1 + } + ], + "id": 8, + "nodeType": "InlineAssembly", + "src": "136:27:0" + } + ] + }, + "functionSelector": "2fbebd38", + "id": 10, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "foo", + "nameLocation": "87:3:0", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 4, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 3, + "mutability": "mutable", + "name": "x", + "nameLocation": "99:1:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "91:9:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "91:7:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "90:11:0" + }, + "returnParameters": { + "id": 7, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "y", + "nameLocation": "131:1:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "123:9:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 5, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "123:7:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "122:11:0" + }, + "scope": 11, + "src": "78:87:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 12, + "src": "59:108:0", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "36:131:0" + } + } + }, + "settings": { + "experimental": true, + "evmVersion": "cancun", + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.object" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_import_ast_yul_identifier_missing_name/output.json b/test/cmdlineTests/standard_import_ast_yul_identifier_missing_name/output.json new file mode 100644 index 000000000000..71d461925829 --- /dev/null +++ b/test/cmdlineTests/standard_import_ast_yul_identifier_missing_name/output.json @@ -0,0 +1,14 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "JSONError: Expected \"name\" to be a string. + +", + "message": "Failed to import AST: Expected \"name\" to be a string.", + "severity": "error", + "type": "JSONError" + } + ], + "sources": {} +} diff --git a/test/cmdlineTests/standard_import_ast_yul_src_not_string/input.json b/test/cmdlineTests/standard_import_ast_yul_src_not_string/input.json new file mode 100644 index 000000000000..0ed9250e8a7d --- /dev/null +++ b/test/cmdlineTests/standard_import_ast_yul_src_not_string/input.json @@ -0,0 +1,222 @@ +{ + "language": "SolidityAST", + "sources": { + "A": { + "ast": { + "absolutePath": "A", + "exportedSymbols": { + "AsmTest": [ + 11 + ] + }, + "id": 12, + "license": "GPL-3.0", + "nodeType": "SourceUnit", + "nodes": [ + { + "id": 1, + "literals": [ + "solidity", + ">=", + "0.0" + ], + "nodeType": "PragmaDirective", + "src": "36:22:0" + }, + { + "abstract": false, + "baseContracts": [], + "canonicalName": "AsmTest", + "contractDependencies": [], + "contractKind": "contract", + "fullyImplemented": true, + "id": 11, + "linearizedBaseContracts": [ + 11 + ], + "name": "AsmTest", + "nameLocation": "68:7:0", + "nodeType": "ContractDefinition", + "nodes": [ + { + "body": { + "id": 9, + "nodeType": "Block", + "src": "134:31:0", + "statements": [ + { + "AST": { + "nativeSrc": "145:18:0", + "nodeType": "YulBlock", + "src": "145:18:0", + "statements": [ + { + "nativeSrc": "147:14:0", + "nodeType": "YulAssignment", + "src": "147:14:0", + "value": { + "arguments": [ + { + "name": "x", + "nativeSrc": "156:1:0", + "nodeType": "YulIdentifier", + "src": "156:1:0" + }, + { + "kind": "number", + "nativeSrc": "159:1:0", + "nodeType": "YulLiteral", + "src": "159:1:0", + "type": "", + "value": "1" + } + ], + "functionName": { + "name": "add", + "nativeSrc": "152:3:0", + "nodeType": "YulIdentifier", + "src": "152:3:0" + }, + "nativeSrc": "152:9:0", + "nodeType": "YulFunctionCall", + "src": 12345 + }, + "variableNames": [ + { + "name": "y", + "nativeSrc": "147:1:0", + "nodeType": "YulIdentifier", + "src": "147:1:0" + } + ] + } + ] + }, + "evmVersion": "cancun", + "externalReferences": [ + { + "declaration": 3, + "isOffset": false, + "isSlot": false, + "src": "156:1:0", + "valueSize": 1 + }, + { + "declaration": 6, + "isOffset": false, + "isSlot": false, + "src": "147:1:0", + "valueSize": 1 + } + ], + "id": 8, + "nodeType": "InlineAssembly", + "src": "136:27:0" + } + ] + }, + "functionSelector": "2fbebd38", + "id": 10, + "implemented": true, + "kind": "function", + "modifiers": [], + "name": "foo", + "nameLocation": "87:3:0", + "nodeType": "FunctionDefinition", + "parameters": { + "id": 4, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 3, + "mutability": "mutable", + "name": "x", + "nameLocation": "99:1:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "91:9:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 2, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "91:7:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "90:11:0" + }, + "returnParameters": { + "id": 7, + "nodeType": "ParameterList", + "parameters": [ + { + "constant": false, + "id": 6, + "mutability": "mutable", + "name": "y", + "nameLocation": "131:1:0", + "nodeType": "VariableDeclaration", + "scope": 10, + "src": "123:9:0", + "stateVariable": false, + "storageLocation": "default", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + }, + "typeName": { + "id": 5, + "name": "uint256", + "nodeType": "ElementaryTypeName", + "src": "123:7:0", + "typeDescriptions": { + "typeIdentifier": "t_uint256", + "typeString": "uint256" + } + }, + "visibility": "internal" + } + ], + "src": "122:11:0" + }, + "scope": 11, + "src": "78:87:0", + "stateMutability": "pure", + "virtual": false, + "visibility": "public" + } + ], + "scope": 12, + "src": "59:108:0", + "usedErrors": [], + "usedEvents": [] + } + ], + "src": "36:131:0" + } + } + }, + "settings": { + "experimental": true, + "evmVersion": "cancun", + "outputSelection": { + "*": { + "*": [ + "evm.bytecode.object" + ] + } + } + } +} diff --git a/test/cmdlineTests/standard_import_ast_yul_src_not_string/output.json b/test/cmdlineTests/standard_import_ast_yul_src_not_string/output.json new file mode 100644 index 000000000000..86a2777f99db --- /dev/null +++ b/test/cmdlineTests/standard_import_ast_yul_src_not_string/output.json @@ -0,0 +1,14 @@ +{ + "errors": [ + { + "component": "general", + "formattedMessage": "JSONError: 'src' must be a string + +", + "message": "Failed to import AST: 'src' must be a string", + "severity": "error", + "type": "JSONError" + } + ], + "sources": {} +}