AsmJsonImporter: Replace validation asserts with proper AstImportError reported as JSONError - #16874
Conversation
|
While working on this, I noticed the generic Before: After (using Happy to open a small separate PR for this if useful, once this one is merged. |
This is intentional and should stay as is. What the handler prints is not a typical error message meant to be shown in the course of normal usage of the compiler. It's more of a crash dump that helps us track down the bug that caused it. If anything, I'd make it more, not less detailed. |
| BOOST_CHECK(!containsError(result, "FatalError", "")); | ||
| } | ||
|
|
||
| BOOST_AUTO_TEST_CASE(import_ast_malformed_inline_assembly) |
There was a problem hiding this comment.
Can these tests be replaced with ASTJSON or astPropertyTests tests? We're trying to reduce the number of Boost-based tests in favor of custom isoltest test cases, which are easier to maintain. I would not add more tests here if we can avoided and even the existing tests should be rewritten with isoltest whenever possible (though this is very low priority).
There was a problem hiding this comment.
Though they do not accommodate error cases currently. We should extend them though so that they can show errors.
There was a problem hiding this comment.
Done — the Boost test is gone entirely. The scenarios now live under test/cmdlineTests/ as standard JSON tests (standard_import_ast_*). ASTJSON/astPropertyTests couldn't host them: they exercise the export direction and take Solidity sources as input, while these need malformed JSON as the input itself.
| // AsmJsonImporter::createStatement/createExpression: yulAssert(nodeType prefix == "Yul") | ||
| { | ||
| Json result = compileWithMutation( | ||
| baseAstJson, | ||
| [](Json& _ast) | ||
| { | ||
| Json* node = findFirstNodeByType(_ast, "YulIdentifier"); | ||
| BOOST_REQUIRE(node); | ||
| (*node)["nodeType"] = "XulIdentifier"; | ||
| }); | ||
| BOOST_REQUIRE(result["errors"][0]["message"].is_string()); | ||
| BOOST_CHECK( | ||
| result["errors"][0]["message"].get<std::string>().find("Failed to import AST: Invalid nodeType prefix") | ||
| != std::string::npos); | ||
| BOOST_CHECK(result["errors"][0]["type"] == "Exception"); | ||
| } |
There was a problem hiding this comment.
We can't do it like this. This basically amounts to testing a failing assertion, i.e. compiler's undefined behavior resulting from a bug:
solidity/libyul/AsmJsonImporter.cpp
Line 92 in 8a07979
Before this code can be tested, it needs to have proper validations. The fact is that AST import is still an experimental feature and is unfinished. It wrongly uses asserts for things that should be proper validations.
If you want to add a test for this, we need to change that. We need to define a proper exception type to represent these failure conditions (they should not come out as just type: Exception). Then change the exporter to throw that exception (or use solRequire() when the validation is a simple one-liner).
There was a problem hiding this comment.
Implemented as suggested: langutil::AstImportError, thrown via solRequire()/solThrow() across AsmJsonImporter, caught by type in StandardCompiler, and reported as JSONError — per the docs that's the type for JSON input not conforming to the required format, while Exception/InternalCompilerError are documented as "report as an issue". Unchecked nlohmann accesses on required string fields are validated the same way now, so they no longer escape as raw type_errors. The new cmdline tests pin the exact check you linked (createStatement's prefix validation). Out of scope here: ASTJsonImporter's astAsserts (the other half of #15854) and non-structural value errors (fromHex digits, oversized number literals).
|
Thanks for the review and the explanation. I see the issue now. It makes sense that these conditions should be handled through proper validation rather than testing failing assertions. I'll look into the suggested approaches and rework the implementation accordingly before updating the tests. |
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 argotorg#15854 (the AsmJsonImporter half).
b7d7097 to
12dbf44
Compare
You're right — withdrawing that suggestion. It makes sense as a crash dump for actual bugs. With this rework the malformed-input cases no longer reach that handler at all. |
Description
Reworked per the review feedback below: from a pure test addition into the validation fix it actually needed.
AsmJsonImporterparses untrusted JSON (the inline assembly subtree of ASTs supplied via the experimentalSolidityASTstandard-json input), but validated it withyulAssert/solAssert. Malformed input therefore surfaced as"type": "Exception"— documented as an internal failure that "should be reported as an issue" — and some unchecked accesses escaped as raw nlohmanntype_errors.Changes:
langutil::AstImportErrorand throw it viasolRequire()/solThrow()for every malformed-input condition inAsmJsonImporter(all 16 former asserts, including the message-less ones).requiredString()helper for JSON string fields that were previously read unchecked (name,kind,hexValue,value,nodeType), so missing or mistyped fields produce a proper message instead of a rawtype_error.StandardCompilerand report it as"type": "JSONError"("JSON input doesn't conform to the required format"), keeping the establishedFailed to import AST:message prefix. The CLI path is unaffected — its broadcatchalready yields the same message.test/cmdlineTests/standard_import_ast_*), one per validation path, including thecreateStatementnodeType prefix check linked in the review.Example — importing an AST whose
YulAssignmentnode has"nodeType": "XulAssignment":"type": "Exception", messageUnknown exception during compilation: ... Failed to import AST: Invalid nodeType prefix"type": "JSONError", messageFailed to import AST: Invalid nodeType prefixPartially addresses #15854 (the
AsmJsonImporterhalf). Out of scope, left for follow-ups:ASTJsonImporter'sastAsserts (the other half of #15854, including the relatedFIXMEinCommandLineInterface), and non-structural value errors (invalid hex digits viafromHex, oversized number literals), which still surface asException.Checklist
AI Disclosure