Zellic / solidity-parser

Solp is a Python library used for reading, parsing and analysis of Solidity source projects and contracts without a dependency on the solc compiler.
https://solp.zellic.io
GNU Affero General Public License v3.0
53 stars 2 forks source link

Crash parsing empty hex literal #4

Closed fcremo closed 1 year ago

fcremo commented 1 year ago

asi is crashing when trying to parse literals in the form of hex"", in a file with pragma solidity ^0.8.20;:

  File "/usr/lib/python3.11/site-packages/click/core.py", line 1130, in __call__
    return self.main(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)
         ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/click/core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/click/core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/click/core.py", line 760, in invoke
    return __callback(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/main.py", line 197, in generate
    mutate_and_write(sol_files, src, out, verbose)
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/main.py", line 55, in mutate_and_write
    output = processFile(fp)
             ^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/main.py", line 45, in processFile
    return add_signoffs(f.read(), fp.name)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/addsignoff.py", line 167, in add_signoffs
    tree = parse_contract(filename, src)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/addsignoff.py", line 76, in parse_contract
    return [ast_parser.make(x) for x in parser.sourceUnit().children]
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/addsignoff.py", line 76, in <listcomp>
    return [ast_parser.make(x) for x in parser.sourceUnit().children]
            ^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/parsers080.py", line 117, in _contract_definition
    parser.make_all_rules(contract_definition.contractBodyElement())
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 70, in make_all_rules
    return map_helper(self.make, [r for r in rules if is_grammar_rule(r)])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 97, in map_helper
    return [func(x) for x in xs]
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 97, in <listcomp>
    return [func(x) for x in xs]
            ^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 52, in make_first
    return self.make(c)
           ^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/parsers080.py", line 188, in _function_definition
    parser.make(function_definition.block())
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/parsers080.py", line 377, in _block
    parser.make_all(block),
    ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 64, in make_all
    return map_helper(self.make, get_grammar_children(rule))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 97, in map_helper
    return [func(x) for x in xs]
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 97, in <listcomp>
    return [func(x) for x in xs]
            ^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 52, in make_first
    return self.make(c)
           ^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 52, in make_first
    return self.make(c)
           ^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/parsers080.py", line 436, in _expr_stmt
    parser.make(stmt.expression())
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/parsers080.py", line 507, in _func_call_expr
    parser.make(func_call_expr.callArgumentList())
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/parsers080.py", line 406, in _call_argument_list
    return parser.make_all(arg_list)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 64, in make_all
    return map_helper(self.make, get_grammar_children(rule))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 97, in map_helper
    return [func(x) for x in xs]
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 97, in <listcomp>
    return [func(x) for x in xs]
            ^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/parsers080.py", line 507, in _func_call_expr
    parser.make(func_call_expr.callArgumentList())
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/parsers080.py", line 406, in _call_argument_list
    return parser.make_all(arg_list)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 64, in make_all
    return map_helper(self.make, get_grammar_children(rule))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 97, in map_helper
    return [func(x) for x in xs]
           ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 97, in <listcomp>
    return [func(x) for x in xs]
            ^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 52, in make_first
    return self.make(c)
           ^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 52, in make_first
    return self.make(c)
           ^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/common.py", line 28, in make
    parsed_rule = subparser(self, rule)
                  ^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/.local/lib/python3.11/site-packages/audit_signoff_injector/solidity_parser/ast/parsers/parsers080.py", line 653, in _hex_string_literal
    return solnodes.Literal(int(total_hex_str, 16))
                            ^^^^^^^^^^^^^^^^^^^^^^
ValueError: invalid literal for int() with base 16: ''
t81lal commented 1 year ago

Hi, is this code in a public repo or is it private? I don't see a case in the solidity docs that allows this case https://docs.soliditylang.org/en/v0.8.20/types.html

fcremo commented 1 year ago

Sorry, took me a while to notice the Github notification. I DMd you the customer for which this was happening, but it should be pretty trivial to recreate the bug by creating a dummy contract with a literal hex"". The incriminated code was part of a test so I think solc accepts this syntax.