-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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 menus Example 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