From ba0ce89f1f5da0f115277301858f478145359ace Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 16 Nov 2022 19:39:18 -0500 Subject: [PATCH 01/13] Fix potential usage of None and Unbound variables issues - Misnamed `src_cmap` - Uninitialized attributes and missing methods due to usage of similar classes that don't inherit the same bases - Better defaults than `None` for variables and attributes when possible and `None` has no special meaning. - Potentially unbound variables - Additional Non checks or type coersion --- Xlib/ext/xinput.py | 7 ++++--- Xlib/protocol/display.py | 33 ++++++++++++++++++--------------- Xlib/protocol/rq.py | 28 +++++++++++++++++++++++----- Xlib/xobject/colormap.py | 2 +- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/Xlib/ext/xinput.py b/Xlib/ext/xinput.py index f9218064..235124b0 100644 --- a/Xlib/ext/xinput.py +++ b/Xlib/ext/xinput.py @@ -226,8 +226,9 @@ def pack_value(self, val): # bytes we build a longer array, being careful to maintain native # byte order across the entire set of values. if sys.byteorder == 'little': - def fun(val): - mask_seq.insert(0, val) + def fun(__v): + # type: (int) -> None + mask_seq.insert(0, __v) elif sys.byteorder == 'big': fun = mask_seq.append else: @@ -378,7 +379,7 @@ def parse_binary_value(self, data, display, length, fmt): } class ClassInfoClass(object): - + check_value = None structcode = None def parse_binary(self, data, display): diff --git a/Xlib/protocol/display.py b/Xlib/protocol/display.py index 56623c35..7b116edb 100644 --- a/Xlib/protocol/display.py +++ b/Xlib/protocol/display.py @@ -369,11 +369,11 @@ def send_request(self, request, wait_for_response): def close_internal(self, whom): # Clear out data structures - self.request_queue = None - self.sent_requests = None - self.event_queue = None - self.data_send = None - self.data_recv = None + self.request_queue = [] + self.sent_requests = [] + self.event_queue = [] + self.data_send = b'' + self.data_recv = b'' # Close the connection self.socket.close() @@ -583,7 +583,7 @@ def send_and_recv(self, flush = None, event = None, request = None, recv = None) i = self.socket.send(self.data_send) except socket.error as err: self.close_internal('server: %s' % err) - raise self.socket_error + raise self.socket_error or Exception() self.data_send = self.data_send[i:] self.data_sent_bytes = self.data_sent_bytes + i @@ -601,12 +601,12 @@ def send_and_recv(self, flush = None, event = None, request = None, recv = None) bytes_recv = self.socket.recv(count) except socket.error as err: self.close_internal('server: %s' % err) - raise self.socket_error + raise self.socket_error or Exception() if not bytes_recv: # Clear up, set a connection closed indicator and raise it self.close_internal('server') - raise self.socket_error + raise self.socket_error or Exception() self.data_recv = bytes(self.data_recv) + bytes_recv gotreq = self.parse_response(request) @@ -690,6 +690,7 @@ def parse_response(self, request): # Parse ordinary server response gotreq = 0 + rtype = None while 1: if self.data_recv: # Check the first byte to find out what kind of response it is @@ -703,7 +704,7 @@ def parse_response(self, request): if rtype == 1: gotreq = self.parse_request_response(request) or gotreq continue - elif rtype & 0x7f == ge.GenericEventCode: + elif rtype and (rtype & 0x7f == ge.GenericEventCode): self.parse_event_response(rtype) continue else: @@ -711,7 +712,7 @@ def parse_response(self, request): # Every response is at least 32 bytes long, so don't bother # until we have received that much - if len(self.data_recv) < 32: + if len(self.data_recv) < 32 or rtype is None: return gotreq # Error response @@ -719,7 +720,7 @@ def parse_response(self, request): gotreq = self.parse_error_response(request) or gotreq # Request response or generic event. - elif rtype == 1 or rtype & 0x7f == ge.GenericEventCode: + elif rtype and rtype == 1 or rtype and (rtype & 0x7f == ge.GenericEventCode): # Set reply length, and loop around to see if # we have got the full response rlen = int(struct.unpack('=L', self.data_recv[4:8])[0]) @@ -812,9 +813,10 @@ def parse_request_response(self, request): def parse_event_response(self, etype): # Skip bit 8, that is set if this event came from an SendEvent - etype = etype & 0x7f + etype = etype and (etype & 0x7f) + is_generic_event_code = etype == ge.GenericEventCode - if etype == ge.GenericEventCode: + if is_generic_event_code: length = self.recv_packet_len else: length = 32 @@ -832,7 +834,7 @@ def parse_event_response(self, etype): e = estruct(display = self, binarydata = self.data_recv[:length]) - if etype == ge.GenericEventCode: + if is_generic_event_code: self.recv_packet_len = 0 self.data_recv = bytesview(self.data_recv, length) @@ -1022,6 +1024,7 @@ def parse_connection_setup(self): class ConnectionSetupRequest(rq.GetAttrData): + _serial = None # type: int | None _request = rq.Struct( rq.Set('byte_order', 1, (0x42, 0x6c)), rq.Pad(1), rq.Card16('protocol_major'), @@ -1061,7 +1064,7 @@ class ConnectionSetupRequest(rq.GetAttrData): def __init__(self, display, *args, **keys): self._binary = self._request.to_binary(*args, **keys) - self._data = None + self._data = {} # Don't bother about locking, since no other threads have # access to the display yet diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 86cb2def..05fe509d 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -110,8 +110,9 @@ class Field(object): f.parse_binary_value() instead. See its documentation string for details. """ - name = None + name = "" default = None + pack_value = None structcode = None structvalues = 0 @@ -185,6 +186,10 @@ class LengthField(Field): structvalues = 1 other_fields = None + def parse_binary_value(self, data = None, display = None, length = None, format = None): + # type: (object, object, object, object) -> tuple[Any, _SliceableBuffer] + return b'', b'' + def calc_length(self, length): """newlen = lf.calc_length(length) @@ -654,10 +659,9 @@ def parse_binary_value(self, data, display, length, format): else: length = int(length) - if format == 0: - ret = None + ret = None - elif format == 8: + if format == 8: ret = (8, data[:length]) data = data[length + ((4 - length % 4) % 4):] @@ -938,6 +942,9 @@ class Field. The fields of a structure are given as arguments object to make conversion as fast as possible. They are generated the first time the methods are called. """ + name = "" + check_value = None # type: Callable[[Any], Any] | None + keyword_args = False def __init__(self, *fields): self.fields = fields @@ -1015,6 +1022,9 @@ def to_binary(self, *varargs, **keys): formats = {} for f in self.var_fields: + if not f.pack_value: + continue + if f.keyword_args: v, l, fm = f.pack_value(field_args[f.name], keys) else: @@ -1273,7 +1283,7 @@ def parse_binary_value(self, data, display, length, format): # string with delta else: - v, data = self.string_textitem.parse_binary(data, display) + v, _ = self.string_textitem.parse_binary(data, display) values.append(v) return values, '' @@ -1288,6 +1298,9 @@ class TextElements16(TextElements8): class GetAttrData(object): + _data = {} # type: dict[str, object] + # GetAttrData classes get their attributes dynamically + # TODO: Complete all classes inheriting from GetAttrData def __getattr__(self, attr): try: if self._data: @@ -1342,6 +1355,7 @@ def __eq__(self, other): class Request(object): + _request = None # type: Struct def __init__(self, display, onerror = None, *args, **keys): self._errorhandler = onerror self._binary = self._request.to_binary(*args, **keys) @@ -1355,6 +1369,7 @@ def _set_error(self, error): return 0 class ReplyRequest(GetAttrData): + _request = None # type: Struct def __init__(self, display, defer = 0, *args, **keys): self._display = display self._binary = self._request.to_binary(*args, **keys) @@ -1372,6 +1387,8 @@ def reply(self): # Send request and wait for reply if we hasn't # already got one. This means that reply() can safely # be called more than one time. + if self._display is None: + raise TypeError self._response_lock.acquire() while self._data is None and self._error is None: @@ -1404,6 +1421,7 @@ def __repr__(self): class Event(GetAttrData): + _fields = None # type: Struct def __init__(self, binarydata = None, display = None, **keys): if binarydata: diff --git a/Xlib/xobject/colormap.py b/Xlib/xobject/colormap.py index 033fb493..a1508d9e 100644 --- a/Xlib/xobject/colormap.py +++ b/Xlib/xobject/colormap.py @@ -44,7 +44,7 @@ def free(self, onerror = None): self.display.free_resource_id(self.id) - def copy_colormap_and_free(self, scr_cmap): + def copy_colormap_and_free(self, src_cmap): mid = self.display.allocate_resource_id() request.CopyColormapAndFree(display = self.display, mid = mid, From d3af1f8e7a935b1f3ced706fac586134d14acbf6 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 16 Nov 2022 19:43:59 -0500 Subject: [PATCH 02/13] Update Xlib/protocol/rq.py --- Xlib/protocol/rq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 05fe509d..15174679 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -1283,7 +1283,7 @@ def parse_binary_value(self, data, display, length, format): # string with delta else: - v, _ = self.string_textitem.parse_binary(data, display) + v, data = self.string_textitem.parse_binary(data, display) values.append(v) return values, '' From 4db982b36400452f197611fde7fb1b71c91a53a5 Mon Sep 17 00:00:00 2001 From: Avasam Date: Wed, 16 Nov 2022 19:47:29 -0500 Subject: [PATCH 03/13] Default to 0 length and 0 format --- Xlib/protocol/rq.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 15174679..972f59f6 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -1211,8 +1211,8 @@ def parse_binary(self, data, display, rawdict = 0): for f in self.var_fields: ret[f.name], data = f.parse_binary_value(data, display, - lengths.get(f.name), - formats.get(f.name), + lengths.get(f.name, 0), + formats.get(f.name, 0), ) if not rawdict: From 18a3f6e9ef372e16711893da3676d0ccf46642b3 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 15:46:07 -0500 Subject: [PATCH 04/13] Data not nullable --- Xlib/protocol/display.py | 2 +- Xlib/protocol/rq.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Xlib/protocol/display.py b/Xlib/protocol/display.py index 7b116edb..e812fedb 100644 --- a/Xlib/protocol/display.py +++ b/Xlib/protocol/display.py @@ -1064,7 +1064,7 @@ class ConnectionSetupRequest(rq.GetAttrData): def __init__(self, display, *args, **keys): self._binary = self._request.to_binary(*args, **keys) - self._data = {} + self._data = {} # type: dict[str, object] # Don't bother about locking, since no other threads have # access to the display yet diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 05fe509d..07c12949 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -1374,7 +1374,7 @@ def __init__(self, display, defer = 0, *args, **keys): self._display = display self._binary = self._request.to_binary(*args, **keys) self._serial = None - self._data = None + self._data = {} # type: dict[str, object] self._error = None self._response_lock = lock.allocate_lock() @@ -1391,7 +1391,7 @@ def reply(self): raise TypeError self._response_lock.acquire() - while self._data is None and self._error is None: + while not self._data and self._error is None: self._display.send_recv_lock.acquire() self._response_lock.release() From fdcc2104d652232855f7a3691f810e687e8a4e0b Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 16:07:46 -0500 Subject: [PATCH 05/13] nonable display in parse_value --- Xlib/protocol/rq.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 66a3befd..36527541 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -307,8 +307,8 @@ def check_value(self, value): return value def parse_value(self, value, display): - # if not display: - # return value + if not display: + return value if value in self.codes: return value @@ -897,8 +897,8 @@ def __init__(self, class_name): self.check_value = None def parse_value(self, value, display): - # if not display: - # return value + if not display: + return value c = display.get_resource_class(self.class_name) if c: return c(display, value) From abec40bc9218cb3955d47e952d4e4be5a044b273 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 17:01:51 -0500 Subject: [PATCH 06/13] XK --- Xlib/XK.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Xlib/XK.py b/Xlib/XK.py index 7603ccd0..4749b542 100644 --- a/Xlib/XK.py +++ b/Xlib/XK.py @@ -24,6 +24,10 @@ # definition modules in the Xlib/keysymdef directory. from Xlib.X import NoSymbol +try: + from typing import TYPE_CHECKING +except ImportError: + TYPE_CHECKING = False def string_to_keysym(keysym): '''Return the (16 bit) numeric code of keysym. @@ -64,7 +68,11 @@ def _load_keysyms_into_XK(mod): # Always import miscellany and latin1 keysyms load_keysym_group('miscellany') +if TYPE_CHECKING: + from Xlib.keysymdef.miscellany import * load_keysym_group('latin1') +if TYPE_CHECKING: + from Xlib.keysymdef.latin1 import * def keysym_to_string(keysym): From e1ecc736eb22b3d11ebdee071f0ef00a045b6da6 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 18:17:27 -0500 Subject: [PATCH 07/13] Update Xlib/protocol/rq.py --- Xlib/protocol/rq.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 36527541..d639d39e 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -112,7 +112,7 @@ class Field(object): """ name = "" default = None - pack_value = None + pack_value = None # type: Callable[[Any], tuple[Any, int | None, int | None]] | None structcode = None structvalues = 0 From b4f44528d9a2352bf60a333d03e71d6bfb26e8a0 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 20:57:05 -0500 Subject: [PATCH 08/13] redundant _data def --- Xlib/protocol/rq.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 36527541..dda517c4 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -1374,7 +1374,6 @@ def __init__(self, display, defer = 0, *args, **keys): self._display = display self._binary = self._request.to_binary(*args, **keys) self._serial = None - self._data = {} # type: dict[str, object] self._error = None self._response_lock = lock.allocate_lock() From 2161afd7a0d751b3f91d88272d49a71e8e5e4882 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 21:04:17 -0500 Subject: [PATCH 09/13] resource_classes init --- Xlib/protocol/display.py | 1 + 1 file changed, 1 insertion(+) diff --git a/Xlib/protocol/display.py b/Xlib/protocol/display.py index e812fedb..c061cc52 100644 --- a/Xlib/protocol/display.py +++ b/Xlib/protocol/display.py @@ -79,6 +79,7 @@ class Display(object): extension_major_opcodes = {} error_classes = error.xerror_class.copy() event_classes = event.event_class.copy() + resource_classes = {} # type: _BaseClasses def __init__(self, display = None): name, protocol, host, displayno, screenno = connect.get_display(display) From 2a2a76ee5975172ceb3998a760d1a16f6b6a2e7c Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 21:42:16 -0500 Subject: [PATCH 10/13] test --- Xlib/protocol/rq.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index 73796704..e3700544 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -186,9 +186,9 @@ class LengthField(Field): structvalues = 1 other_fields = None - def parse_binary_value(self, data = None, display = None, length = None, format = None): - # type: (object, object, object, object) -> tuple[Any, _SliceableBuffer] - return b'', b'' + # def parse_binary_value(self, data = None, display = None, length = None, format = None): + # # type: (object, object, object, object) -> tuple[Any, _SliceableBuffer] + # return b'', b'' def calc_length(self, length): """newlen = lf.calc_length(length) @@ -1303,11 +1303,8 @@ class GetAttrData(object): # TODO: Complete all classes inheriting from GetAttrData def __getattr__(self, attr): try: - if self._data: - return self._data[attr] - else: - raise AttributeError(attr) - except KeyError: + return self._data[attr] + except (KeyError, AttributeError): raise AttributeError(attr) class DictWrapper(GetAttrData): From 4081dd0b6ed65fe605692685d36bc63888fa0b90 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 21:51:28 -0500 Subject: [PATCH 11/13] debug --- Xlib/display.py | 12 +++++++++--- Xlib/protocol/display.py | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/Xlib/display.py b/Xlib/display.py index e0f7b5c8..f36ed6a0 100644 --- a/Xlib/display.py +++ b/Xlib/display.py @@ -379,9 +379,15 @@ def keysym_to_keycode(self, keysym): lowest code is returned. If keysym is not bound to any key, 0 is returned.""" try: - return self._keymap_syms[keysym][0][1] - except (KeyError, IndexError): - return 0 + return (1, self._keymap_syms[keysym][0][1]) + except: + try: + return (2, self._keymap_syms[keysym][0]) + except: + try: + return (3, self._keymap_syms[keysym]) + except: + return (4, self._keymap_syms) def keysym_to_keycodes(self, keysym): """Look up all the keycodes that is bound to keysym. A list of diff --git a/Xlib/protocol/display.py b/Xlib/protocol/display.py index c061cc52..df5ffb07 100644 --- a/Xlib/protocol/display.py +++ b/Xlib/protocol/display.py @@ -721,7 +721,7 @@ def parse_response(self, request): gotreq = self.parse_error_response(request) or gotreq # Request response or generic event. - elif rtype and rtype == 1 or rtype and (rtype & 0x7f == ge.GenericEventCode): + elif rtype == 1 or (rtype & 0x7f == ge.GenericEventCode): # Set reply length, and loop around to see if # we have got the full response rlen = int(struct.unpack('=L', self.data_recv[4:8])[0]) From 81da35c26e711e28e9cbc064dfae90aad62c46cb Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 22:33:56 -0500 Subject: [PATCH 12/13] Nonable length --- Xlib/ext/xinput.py | 2 ++ Xlib/protocol/display.py | 6 +++--- Xlib/protocol/rq.py | 14 ++++++++------ 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Xlib/ext/xinput.py b/Xlib/ext/xinput.py index 235124b0..1ad98d41 100644 --- a/Xlib/ext/xinput.py +++ b/Xlib/ext/xinput.py @@ -309,6 +309,8 @@ def __init__(self, name): rq.ValueField.__init__(self, name) def parse_binary_value(self, data, display, length, fmt): + if length is None: + length = len(data) # Mask: bitfield of button states. mask_len = 4 * ((((length + 7) >> 3) + 3) >> 2) mask_data = data[:mask_len] diff --git a/Xlib/protocol/display.py b/Xlib/protocol/display.py index df5ffb07..ef47c6b0 100644 --- a/Xlib/protocol/display.py +++ b/Xlib/protocol/display.py @@ -361,12 +361,12 @@ def send_request(self, request, wait_for_response): self.request_serial = (self.request_serial + 1) % 65536 self.request_queue.append((request, wait_for_response)) - qlen = len(self.request_queue) + # qlen = len(self.request_queue) self.request_queue_lock.release() -# if qlen > 10: -# self.flush() + # if qlen > 10: + # self.flush() def close_internal(self, whom): # Clear out data structures diff --git a/Xlib/protocol/rq.py b/Xlib/protocol/rq.py index e3700544..fb668292 100644 --- a/Xlib/protocol/rq.py +++ b/Xlib/protocol/rq.py @@ -186,9 +186,9 @@ class LengthField(Field): structvalues = 1 other_fields = None - # def parse_binary_value(self, data = None, display = None, length = None, format = None): - # # type: (object, object, object, object) -> tuple[Any, _SliceableBuffer] - # return b'', b'' + def parse_binary_value(self, data = None, display = None, length = None, format = None): + # type: (object, object, object, object) -> tuple[Any, _SliceableBuffer] + return b'', b'' def calc_length(self, length): """newlen = lf.calc_length(length) @@ -474,7 +474,9 @@ def pack_value(self, val): return struct.pack('>' + 'H' * slen, *val) + pad, slen, None def parse_binary_value(self, data, display, length, format): - if length == 'odd': + if length is None: + length = len(data) + elif length == 'odd': length = len(data) // 2 - 1 elif length == 'even': length = len(data) // 2 @@ -1211,8 +1213,8 @@ def parse_binary(self, data, display, rawdict = 0): for f in self.var_fields: ret[f.name], data = f.parse_binary_value(data, display, - lengths.get(f.name, 0), - formats.get(f.name, 0), + lengths.get(f.name), + formats.get(f.name), ) if not rawdict: From d3bd0985684dad1b8c3c9d034890ee09543aa108 Mon Sep 17 00:00:00 2001 From: Avasam Date: Fri, 18 Nov 2022 22:47:56 -0500 Subject: [PATCH 13/13] undo debug --- Xlib/display.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/Xlib/display.py b/Xlib/display.py index f36ed6a0..e0f7b5c8 100644 --- a/Xlib/display.py +++ b/Xlib/display.py @@ -379,15 +379,9 @@ def keysym_to_keycode(self, keysym): lowest code is returned. If keysym is not bound to any key, 0 is returned.""" try: - return (1, self._keymap_syms[keysym][0][1]) - except: - try: - return (2, self._keymap_syms[keysym][0]) - except: - try: - return (3, self._keymap_syms[keysym]) - except: - return (4, self._keymap_syms) + return self._keymap_syms[keysym][0][1] + except (KeyError, IndexError): + return 0 def keysym_to_keycodes(self, keysym): """Look up all the keycodes that is bound to keysym. A list of pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy