Optimize paste from clipboard#17
Conversation
|
What is the use case for this? Can you make an example? Probably I will not merge it, because using eval on untrusted strings is a security issue. See https://stackoverflow.com/a/10964364 |
An example would be this:
Yes, I know. I was considering |
daca13f to
88f3cec
Compare
|
[EDITED] Updated code with improved robustness on the Python expression evaluation from clipboard, using the safe_tokens configuration variable, which defines a restricted list of safe tokens to be used. The code also allows usage of numbers, strings (but not f-strings) and operands, so that standard math, byte and string expressions can be used. Optionally, safe_tokens can be overridden for specific purposes. The code cannot protect from any attach, like inputting an expression that evaluates to a huge number: Perhaps for dev/testing use, this could be anyway acceptable. |
88f3cec to
1aea013
Compare
|
An alternative method would be to add a menu toggle to the hex editor, allowing pasting Python expressions. I'll try working on such a mode as soon as I have time. |
1aea013 to
66be153
Compare
|
This is an almost complete rewrite of the previous code which enhances the default mode of the paste from clipboard interpreter of the hex editor (now hex strings copied from a wide variety of tracers can be directly pasted to the hex editor) and also adds a menu toggle, allowing pasting Python expressions from the clipboard, with robust evaluation: other than using the safe_tokens configuration variable, which defines a restricted list of safe tokens to be interpreted, the code catches most (if not all) the existing "eval" exploits (f-strings, long-running math computations, tokens). Examples of strings allowed with the default paste mode: Examples of strings allowed with the Python paste mode: bytes.fromhex("71 20 98 00 c0 7a 3e 6a 8d 7c c4 0d 04 10 02 f2 00")
b'\x00\x00\x00\xa4\xc18\xe1\x81_\x00\xcc#b\x0c\r\x15'
bytes.fromhex("0102030405060708090a0b0c0d0e0f" + "000101")Examples of appropriately discarded Python strings when using the Python paste mode: 2 ** 2 ** 2 ** 2
"()"*8**5
'(1,' * 100 + ')' * 100
10**10**100
"foo" + f"{().__class__.__base__}"
"foo" + "bar"
bytes.fromhex("0102030405060708090a0b0c0d0e0f" + f"{().__class__.__base__}")
1 + "two"
2/0
1,2,3
import time |
|
Thanks for your work on my project. I still don't like the approach with eval though. That's too much magic happening in the background that a user would never expect when inserting. Even though you put some effort into it, I'm not going to merge it that way. But I like the improvements of the string parsing. Maybe the following format would be practical, which I often have in C/C++ code: |
I do not want to further insist on the usage of eval, just inform that, pasting |
developing a plugin looks fine
OK, I'll try to work out a possible solution without using eval and supporting constructs like |
66be153 to
d31a418
Compare
|
Code revised to support the following formats (with no usage of eval): Optionally, a plugin might be implemented by overriding methods in the from construct_editor.wx_widgets.wx_hex_editor import (
HexEditorGrid, ContextMenuItem)
class HexEditorGrid(HexEditorGrid):
...
def build_context_menu(self):
menus = super().build_context_menu()
... # process the "menus" list
return menus
def string_to_byts(self, byts_str: str):
...
return super().string_to_byts(byts_str)Monkey patch: import construct_editor as cseditor
from myplugin import HexEditorGrid
...
cseditor.wx_widgets.wx_hex_editor.HexEditorGrid = HexEditorGrid
...
editor_panel = cseditor.wx_widgets.WxConstructHexEditor(...)Example of build_context_menu override: def build_context_menu(self):
menus = super().build_context_menu()
menus.Append(None) # separator
menus.Append(
ContextMenuItem(
wx_id=wx.ID_ANY,
name="my new context menu toggle",
callback=lambda event: self.my_specific_function(),
toggle_state=my_state, # None = option, True = toggle selected, False = toggle unselected
enabled=not self.read_only,
)
)
return menusExample of string_to_byts override: def string_to_byts(self, byts_str: str):
if my_condition:
return my_string_processor(byts_str)
else:
return super().string_to_byts(byts_str) |
d31a418 to
2ba7b59
Compare
|
Thanks for your contribution. I will merge this PR. But I am also working on an different branch where I refactored many files in this repository. But I applied your changes to the other branch manually, with a few modifications. The next release will be based on the refactored branch. |
Allow pasting Python expressions from the clipboard