checkov icon indicating copy to clipboard operation
checkov copied to clipboard

Bicep: Missing parser support for `extension` keyword

Open MadsVSChristensen opened this issue 3 months ago • 3 comments

Describe the issue The bicep parser doesn't support the extension keyword and throws a parsing error when it encounters it in a file.

I've created a pull request fixing the issue at the pycep repo.

Error ouput:

2025-11-10 09:09:05,065 [MainThread  ] [INFO ]  [bicep] start to parse 1 files
2025-11-10 09:09:05,084 [MainThread  ] [DEBUG]  [bicep] Couldn't parse main.bicep
Traceback (most recent call last):
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/lark/lexer.py", line 689, in lex
    yield lexer.next_token(lexer_state, parser_state)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/lark/lexer.py", line 622, in next_token
    raise UnexpectedCharacters(lex_state.text.text, line_ctr.char_pos, line_ctr.line, line_ctr.column,
lark.exceptions.UnexpectedCharacters: No terminal matches 'e' in the current parser context, at line 8 col 1

extension microsoftGraphV1
^
Expected one of: 
        * VAR
        * TYPE
        * OUTPUT
        * _CPP_COMMENT_NL
        * MODULE
        * AT
        * TARGETSCOPE
        * PARAM
        * METADATA
        * RESOURCE

Previous tokens: Token('_CPP_COMMENT_NL', '// Enable Microsoft Graph extension\n')


During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/checkov/bicep/parser.py", line 24, in parse
    template = self.bicep_parser.parse(text=content)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/pycep/main.py", line 29, in parse
    tree = self._create_tree(text=text, file_path=file_path)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/pycep/main.py", line 53, in _create_tree
    return self.lark_parser.parse(bicep_text)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/lark/lark.py", line 677, in parse
    return self.parser.parse(text, start=start, on_error=on_error)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/lark/parser_frontends.py", line 131, in parse
    return self.parser.parse(stream, chosen_start, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/lark/parsers/lalr_parser.py", line 42, in parse
    return self.parser.parse(lexer, start)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/lark/parsers/lalr_parser.py", line 88, in parse
    return self.parse_from_state(parser_state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/lark/parsers/lalr_parser.py", line 111, in parse_from_state
    raise e
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/lark/parsers/lalr_parser.py", line 100, in parse_from_state
    for token in state.lexer.lex(state):
                 ^^^^^^^^^^^^^^^^^^^^^^
  File ".../.cache/uv/archive-v0/byuoiA4g8gpozKNsrLhzc/lib/python3.12/site-packages/lark/lexer.py", line 698, in lex
    raise UnexpectedToken(token, e.allowed, state=parser_state, token_history=[last_token], terminals_by_name=self.root_lexer.terminals_by_name)
lark.exceptions.UnexpectedToken: Unexpected token Token('STRING', 'extension') at line 8, column 1.
Expected one of: 
        * VAR
        * TYPE
        * OUTPUT
        * _CPP_COMMENT_NL
        * MODULE
        * AT
        * TARGETSCOPE
        * PARAM
        * METADATA
        * RESOURCE
        * $END
Previous tokens: [Token('_CPP_COMMENT_NL', '// Enable Microsoft Graph extension\n')]

Example Value

// Simple extension
extension microsoftGraphV1

// Extension with config and alias
extension kubernetes with {
  namespace: 'default'
  kubeConfig: 'someKubeConfig'
} as k8s

// ... Do something with it

MadsVSChristensen avatar Nov 10 '25 08:11 MadsVSChristensen

Thanks @MadsVSChristensen , is there anything else that needs to be done on checkov side or this can be closed?

maxamel avatar Nov 12 '25 05:11 maxamel

As far as I can tell, this has only been released to pypi as a beta release, at this time (link). Once the change is in a stable release, you will need to update the version in the Pipfile. The current version is pinned to pycep-parser = "==0.5.1". (Tagging @gruebel to see if he can provide an update on that.) No other change should be needed.

MadsVSChristensen avatar Nov 12 '25 08:11 MadsVSChristensen

@maxamel Yesterday, @gruebel release version 0.6.1, so all you need to do is update your dependency.

MadsVSChristensen avatar Nov 24 '25 20:11 MadsVSChristensen