mirror of
https://github.com/mandiant/capa.git
synced 2026-06-12 19:11:32 -07:00
fix: guard get_operand_expressions against empty expression tree
`_build_expression_tree` already returns `[]` for the Ghidra bug where an operand has no expressions (see https://github.com/NationalSecurityAgency/ghidra/issues/6817), but `get_operand_expressions` then called the recursive walker unconditionally with `tree_index=0`, which indexed into the empty list and raised `IndexError`. Add an early-return guard so callers receive `[]` instead.
This commit is contained in:
committed by
Willi Ballenthin
parent
5d43fc8fe3
commit
197a84d267
@@ -32,6 +32,7 @@
|
||||
- fix: loader.py reads entire file for magic byte check @williballenthin #3029
|
||||
- fix: freeze/__init__.py: logically impossible condition @williballenthin #3030
|
||||
- fix: EXTENSIONS_ELF never referenced @williballenthin #3031
|
||||
- fix: guard get_operand_expressions against empty expression tree so Ghidra-exported BinExport2 files with empty operands no longer raise IndexError @williballenthin
|
||||
- fix: add return after zero-offset yield in extract_insn_offset_features so Offset(0) is not emitted twice @williballenthin
|
||||
- fix: use f-string in binexport2 extractor so unexpected global feature value appears in ValueError message @williballenthin
|
||||
- fix: correct scale/displacement expressions in get_operand_phrase_info 5-expression branch (used expression3 operator instead of expression4 value) @williballenthin
|
||||
|
||||
@@ -333,6 +333,8 @@ def _fill_operand_expression_list(
|
||||
|
||||
def get_operand_expressions(be2: BinExport2, op: BinExport2.Operand) -> list[BinExport2.Expression]:
|
||||
tree = _build_expression_tree(be2, op)
|
||||
if not tree:
|
||||
return []
|
||||
|
||||
expressions: list[BinExport2.Expression] = []
|
||||
_fill_operand_expression_list(be2, op, tree, 0, expressions)
|
||||
|
||||
@@ -340,6 +340,26 @@ BE2 = ParseDict(
|
||||
)
|
||||
|
||||
|
||||
def test_get_operand_expressions_empty_operand():
|
||||
be2 = ParseDict(
|
||||
{
|
||||
"expression": [
|
||||
{"type": BinExport2.Expression.REGISTER, "symbol": "x0"},
|
||||
],
|
||||
"operand": [
|
||||
{"expression_index": [0]},
|
||||
{},
|
||||
],
|
||||
},
|
||||
BinExport2(),
|
||||
)
|
||||
normal_op = be2.operand[0]
|
||||
empty_op = be2.operand[1]
|
||||
|
||||
assert len(get_operand_expressions(be2, normal_op)) == 1
|
||||
assert get_operand_expressions(be2, empty_op) == []
|
||||
|
||||
|
||||
def test_is_stack_register_expression():
|
||||
mov = ParseDict(BE2_DICT["instruction"][0], BinExport2.Instruction())
|
||||
add = ParseDict(BE2_DICT["instruction"][2], BinExport2.Instruction())
|
||||
|
||||
Reference in New Issue
Block a user