Skip to content

Commit

Permalink
Merge pull request #82 from trailofbits/sh/opcodes
Browse files Browse the repository at this point in the history
Add support for OBJ and BINSTRING
  • Loading branch information
suhacker1 authored Jan 3, 2024
2 parents 4ef7f81 + d1e99d1 commit 4503d1c
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 0 deletions.
36 changes: 36 additions & 0 deletions fickling/fickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,26 @@ def run(self, interpreter: Interpreter):
return objs


class Obj(Opcode):
name = "OBJ"

def run(self, interpreter: Interpreter):
args = []
while interpreter.stack:
arg = interpreter.stack.pop()
if isinstance(arg, MarkObject):
break
args.insert(0, arg)
else:
raise ValueError("Exhausted the stack while searching for a MarkObject!")
kls = args.pop(0)
# TODO Verify paths for correctness
if args or hasattr(kls, "__getinitargs__") or not isinstance(kls, type):
interpreter.stack.append(ast.Call(kls, args, []))
else:
interpreter.stack.append(ast.Call(kls, kls, []))


class ShortBinUnicode(DynamicLength, ConstantOpcode):
name = "SHORT_BINUNICODE"
priority = 5000
Expand Down Expand Up @@ -1475,6 +1495,22 @@ def validate(cls, obj):
return obj


class BinString(DynamicLength, ConstantOpcode):
name = "BINSTRING"
priority = ShortBinBytes.priority + 1
length_bytes = 4
signed = True

def encode_body(self) -> bytes:
return repr(self.arg).encode("utf-8")

@classmethod
def validate(cls, obj):
if not isinstance(obj, str):
raise ValueError(f"String must be instantiated from a str, not {obj!r}")
return super().validate(obj)


class BinBytes(ShortBinBytes):
name = "BINBYTES"
priority = ShortBinBytes.priority + 1
Expand Down
5 changes: 5 additions & 0 deletions test/test_crashes.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,8 @@ def test_pop_mark(self):
"""Tests the correctness of the POP_MARK opcode by using the bytecode from https://github.com/mindspore-ai/mindspore/issues/183
This can be simplified to allow for the correctness of additional opcodes to be tested"""
pass

@unparse_test(io.BytesIO(b'(cos\nsystem\nS"whoami"\no.'))
def test_obj(self):
"""Tests the correctness of the OBJ opcode"""
pass

0 comments on commit 4503d1c

Please sign in to comment.