Skip to content

'IndexError: list index out of range' raised calling vyper.compiler.compile_code with 54 double quotes #2258

@agroce

Description

@agroce

Version Information

  • vyper Version (output of vyper --version): 0.2.8+commit.d145722
  • OS: ubuntu 20.04 (on docker on osx)
  • Python Version (output of python --version): Python 3.8.5
  • Environment (output of pip freeze):
    asttokens==2.0.4
    Cython==0.29.21
    dbus-python==1.2.16
    pycryptodome==3.9.9
    Pygments==2.3.1
    PyGObject==3.36.0
    python-afl==0.7.3
    PyYAML==5.3.1
    semantic-version==2.8.5
    six==1.15.0
    vyper==0.2.8

What's your issue about?

>>> import vyper.compiler
>>> vyper.compiler.compile_code('\r[[]]\ndef _(e:[],l:[]):\n    """"""""""""""""""""""""""""""""""""""""""""""""""""""\n    f.n()')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/__init__.py", line 151, in compile_code
    return compile_codes(
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/opcodes.py", line 222, in _wrapper
    return fn(*args, **kwargs)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/__init__.py", line 110, in compile_codes
    raise exc
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/__init__.py", line 105, in compile_codes
    out[contract_name][output_format] = OUTPUT_FORMATS[output_format](compiler_data)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/output.py", line 138, in build_bytecode_output
    return f"0x{compiler_data.bytecode.hex()}"
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 126, in bytecode
    self._bytecode = generate_bytecode(self.assembly)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 114, in assembly
    self._assembly = generate_assembly(self.lll_nodes)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 102, in lll_nodes
    self._gen_lll()
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 97, in _gen_lll
    self._lll_nodes, self._lll_runtime = generate_lll_nodes(self.global_ctx)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 90, in global_ctx
    self.vyper_module_folded, self.interface_codes
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 81, in vyper_module_folded
    self._vyper_module_folded = generate_folded_ast(self.vyper_module)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 74, in vyper_module
    self._vyper_module = generate_ast(self.source_code, self.source_id, self.contract_name)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 154, in generate_ast
    return vy_ast.parse_to_ast(source_code, source_id, contract_name)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/ast/utils.py", line 36, in parse_to_ast
    annotate_python_ast(py_ast, source_code, class_types, source_id, contract_name)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/ast/annotation.py", line 281, in annotate_python_ast
    tokens = asttokens.ASTTokens(source_code, tree=parsed_ast)
  File "/usr/local/lib/python3.8/dist-packages/asttokens-2.0.4-py3.8.egg/asttokens/asttokens.py", line 65, in __init__
    self.mark_tokens(self._tree)
  File "/usr/local/lib/python3.8/dist-packages/asttokens-2.0.4-py3.8.egg/asttokens/asttokens.py", line 76, in mark_tokens
    MarkTokens(self).visit_tree(root_node)
  File "/usr/local/lib/python3.8/dist-packages/asttokens-2.0.4-py3.8.egg/asttokens/mark_tokens.py", line 49, in visit_tree
    util.visit_tree(node, self._visit_before_children, self._visit_after_children)
  File "/usr/local/lib/python3.8/dist-packages/asttokens-2.0.4-py3.8.egg/asttokens/util.py", line 199, in visit_tree
    ret = postvisit(current, par_value, value)
  File "/usr/local/lib/python3.8/dist-packages/asttokens-2.0.4-py3.8.egg/asttokens/mark_tokens.py", line 92, in _visit_after_children
    nfirst, nlast = self._methods.get(self, node.__class__)(node, first, last)
  File "/usr/local/lib/python3.8/dist-packages/asttokens-2.0.4-py3.8.egg/asttokens/mark_tokens.py", line 189, in handle_attr
    name = self._code.next_token(dot)
  File "/usr/local/lib/python3.8/dist-packages/asttokens-2.0.4-py3.8.egg/asttokens/asttokens.py", line 141, in next_token
    while is_non_coding_token(self._tokens[i].type):
IndexError: list index out of range

Note that this (like all fuzzing bugs I'll report) is minimized: removing one of the quotes makes it properly raise a SyntaxException:

>>> vyper.compiler.compile_code('\r[[]]\ndef _(e:[],l:[]):\n    """""""""""""""""""""""""""""""""""""""""""""""""""""\n    f.n()')
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/ast/pre_parser.py", line 112, in pre_parse
    token_list = list(tokenize(io.BytesIO(code_bytes).readline))
  File "/usr/lib/python3.8/tokenize.py", line 461, in _tokenize
    raise TokenError("EOF in multi-line string", strstart)
tokenize.TokenError: ('EOF in multi-line string', (3, 52))

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/__init__.py", line 151, in compile_code
    return compile_codes(
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/opcodes.py", line 222, in _wrapper
    return fn(*args, **kwargs)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/__init__.py", line 110, in compile_codes
    raise exc
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/__init__.py", line 105, in compile_codes
    out[contract_name][output_format] = OUTPUT_FORMATS[output_format](compiler_data)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/output.py", line 138, in build_bytecode_output
    return f"0x{compiler_data.bytecode.hex()}"
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 126, in bytecode
    self._bytecode = generate_bytecode(self.assembly)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 114, in assembly
    self._assembly = generate_assembly(self.lll_nodes)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 102, in lll_nodes
    self._gen_lll()
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 97, in _gen_lll
    self._lll_nodes, self._lll_runtime = generate_lll_nodes(self.global_ctx)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 90, in global_ctx
    self.vyper_module_folded, self.interface_codes
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 81, in vyper_module_folded
    self._vyper_module_folded = generate_folded_ast(self.vyper_module)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 74, in vyper_module
    self._vyper_module = generate_ast(self.source_code, self.source_id, self.contract_name)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/compiler/phases.py", line 154, in generate_ast
    return vy_ast.parse_to_ast(source_code, source_id, contract_name)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/ast/utils.py", line 30, in parse_to_ast
    class_types, reformatted_code = pre_parse(source_code)
  File "/usr/local/lib/python3.8/dist-packages/vyper-0.2.8-py3.8.egg/vyper/ast/pre_parser.py", line 159, in pre_parse
    raise SyntaxException(e.args[0], code, e.args[1][0], e.args[1][1]) from e
vyper.exceptions.SyntaxException: EOF in multi-line string
  line 3:52 
       2 [[]]
  ---> 3 def _(e:[],l:[]):
  -----------------------------------------------------------^
       4     """""""""""""""""""""""""""""""""""""""""""""""""""""

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugBug that shouldn't change language semantics when fixed.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions