From 798a553e102babe1e196c321c4225d49c9a3fde9 Mon Sep 17 00:00:00 2001 From: Suha Sabi Hussain Date: Thu, 21 Dec 2023 11:23:41 -0500 Subject: [PATCH 1/6] Add OBJ opcode with test --- fickling/fickle.py | 20 ++++++++++++++++++++ test/test_crashes.py | 9 +++++++++ 2 files changed, 29 insertions(+) diff --git a/fickling/fickle.py b/fickling/fickle.py index 9a327c2..47a1b80 100644 --- a/fickling/fickle.py +++ b/fickling/fickle.py @@ -1122,6 +1122,26 @@ def run(self, interpreter: Interpreter): raise ValueError("Exhausted the stack while searching for a MarkObject!") 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.append(arg) + else: + raise ValueError("Exhausted the stack while searching for a MarkObject!") + kls = args.pop() + # TODO emulate stack after to verify correctness + if (args or hasattr(kls, "__getinitargs__") or not isinstance(kls, type)): + interpreter.stack.append(ast.Call(kls, [list(args)], [])) + else: + interpreter.stack.append(ast.Call(kls, kls, [])) + class ShortBinUnicode(DynamicLength, ConstantOpcode): name = "SHORT_BINUNICODE" diff --git a/test/test_crashes.py b/test/test_crashes.py index d69f1c9..84eff94 100644 --- a/test/test_crashes.py +++ b/test/test_crashes.py @@ -62,3 +62,12 @@ 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): + pass + From 56f02e0c188d5eadfa4a99b535ebe1e4bea14487 Mon Sep 17 00:00:00 2001 From: Suha Sabi Hussain Date: Thu, 21 Dec 2023 12:36:00 -0500 Subject: [PATCH 2/6] Add BINSTRING --- fickling/fickle.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/fickling/fickle.py b/fickling/fickle.py index 47a1b80..212305b 100644 --- a/fickling/fickle.py +++ b/fickling/fickle.py @@ -75,7 +75,6 @@ class MarkObject: class Opcode: name: str info: OpcodeInfo - def __init__( self, argument: Optional[Any] = None, @@ -1122,8 +1121,8 @@ def run(self, interpreter: Interpreter): raise ValueError("Exhausted the stack while searching for a MarkObject!") return objs - -class OBJ(Opcode): + +class Obj(Opcode): name = "OBJ" def run(self, interpreter: Interpreter): @@ -1136,7 +1135,7 @@ def run(self, interpreter: Interpreter): else: raise ValueError("Exhausted the stack while searching for a MarkObject!") kls = args.pop() - # TODO emulate stack after to verify correctness + # TODO Verify paths for correctness if (args or hasattr(kls, "__getinitargs__") or not isinstance(kls, type)): interpreter.stack.append(ast.Call(kls, [list(args)], [])) else: @@ -1488,6 +1487,21 @@ def validate(cls, obj): raise ValueError(f"String must be instantiated from a str, not {obj!r}") 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 obj + class BinBytes(ShortBinBytes): name = "BINBYTES" From 9d415cb57d8a093db38a7f2ce45ee78aab4c5fd3 Mon Sep 17 00:00:00 2001 From: Suha Sabi Hussain Date: Thu, 21 Dec 2023 12:37:26 -0500 Subject: [PATCH 3/6] Lint --- fickling/fickle.py | 6 ++++-- test/test_crashes.py | 7 +------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/fickling/fickle.py b/fickling/fickle.py index 212305b..a02b2f6 100644 --- a/fickling/fickle.py +++ b/fickling/fickle.py @@ -75,6 +75,7 @@ class MarkObject: class Opcode: name: str info: OpcodeInfo + def __init__( self, argument: Optional[Any] = None, @@ -1136,11 +1137,11 @@ def run(self, interpreter: Interpreter): raise ValueError("Exhausted the stack while searching for a MarkObject!") kls = args.pop() # TODO Verify paths for correctness - if (args or hasattr(kls, "__getinitargs__") or not isinstance(kls, type)): + if args or hasattr(kls, "__getinitargs__") or not isinstance(kls, type): interpreter.stack.append(ast.Call(kls, [list(args)], [])) else: interpreter.stack.append(ast.Call(kls, kls, [])) - + class ShortBinUnicode(DynamicLength, ConstantOpcode): name = "SHORT_BINUNICODE" @@ -1487,6 +1488,7 @@ def validate(cls, obj): raise ValueError(f"String must be instantiated from a str, not {obj!r}") return obj + class BinString(DynamicLength, ConstantOpcode): name = "BINSTRING" priority = ShortBinBytes.priority + 1 diff --git a/test/test_crashes.py b/test/test_crashes.py index 84eff94..79d3831 100644 --- a/test/test_crashes.py +++ b/test/test_crashes.py @@ -63,11 +63,6 @@ def test_pop_mark(self): 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.') - ) + @unparse_test(io.BytesIO(b'(cos\nsystem\nS"whoami"\no.')) def test_obj(self): pass - From a64681b116dc5a1bb5307addcc433408727f5abe Mon Sep 17 00:00:00 2001 From: Suha Sabi Hussain Date: Wed, 3 Jan 2024 08:29:57 -0500 Subject: [PATCH 4/6] Call super().validate() Co-authored-by: Boyan MILANOV --- fickling/fickle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fickling/fickle.py b/fickling/fickle.py index a02b2f6..7955341 100644 --- a/fickling/fickle.py +++ b/fickling/fickle.py @@ -1502,7 +1502,7 @@ def encode_body(self) -> bytes: def validate(cls, obj): if not isinstance(obj, str): raise ValueError(f"String must be instantiated from a str, not {obj!r}") - return obj + return super().validate(obj) class BinBytes(ShortBinBytes): From 3533cb812bffb0f960552d804b861a79e2fafec7 Mon Sep 17 00:00:00 2001 From: Suha Sabi Hussain Date: Wed, 3 Jan 2024 08:30:17 -0500 Subject: [PATCH 5/6] Invert list order Co-authored-by: Boyan MILANOV --- fickling/fickle.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fickling/fickle.py b/fickling/fickle.py index 7955341..ccc8a36 100644 --- a/fickling/fickle.py +++ b/fickling/fickle.py @@ -1132,13 +1132,13 @@ def run(self, interpreter: Interpreter): arg = interpreter.stack.pop() if isinstance(arg, MarkObject): break - args.append(arg) + args.insert(0, arg) else: raise ValueError("Exhausted the stack while searching for a MarkObject!") - kls = args.pop() + 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, [list(args)], [])) + interpreter.stack.append(ast.Call(kls, args, [])) else: interpreter.stack.append(ast.Call(kls, kls, [])) From d1e99d1024f61c8c6651c13534c14d533907f19b Mon Sep 17 00:00:00 2001 From: Suha Sabi Hussain Date: Wed, 3 Jan 2024 10:22:06 -0500 Subject: [PATCH 6/6] Add comment --- test/test_crashes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test_crashes.py b/test/test_crashes.py index 79d3831..43c3c73 100644 --- a/test/test_crashes.py +++ b/test/test_crashes.py @@ -65,4 +65,5 @@ def test_pop_mark(self): @unparse_test(io.BytesIO(b'(cos\nsystem\nS"whoami"\no.')) def test_obj(self): + """Tests the correctness of the OBJ opcode""" pass