From 5e3b735087ec089bc452eace9474c1593a083a85 Mon Sep 17 00:00:00 2001 From: Terry Simons Date: Tue, 18 Apr 2017 14:44:23 -0700 Subject: [PATCH 1/7] Fix Python 3.6.0 --- usbinfo/darwin.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/usbinfo/darwin.py b/usbinfo/darwin.py index 2c02f14..5701235 100755 --- a/usbinfo/darwin.py +++ b/usbinfo/darwin.py @@ -38,9 +38,13 @@ def _ioreg(nodename): """Run ioreg command on specific node name""" cmd = ['ioreg', '-a', '-l', '-r', '-n', nodename] output = subprocess.check_output(cmd) + plist_data = [] if output: - return plistlib.readPlistFromString(output) - return [] + try: + plist_data = plistlib.readPlistFromString(output) + except AttributeError as e: + plist_data = plistlib.loads(output) + return plist_data if nodename is None: xhci = _ioreg('AppleUSBXHCI') @@ -97,7 +101,7 @@ def _disk_partition(node): info = {} for child in node.get('IORegistryEntryChildren', []): - for class_name, handler in ioclass_handlers.iteritems(): + for class_name, handler in ioclass_handlers.items(): if child.get('IOObjectClass') == class_name: info.update(handler(child)) info.update(_extra_if_info(child)) From 532cf1f926fe7904495bdc4021bdfabfdae8b0a4 Mon Sep 17 00:00:00 2001 From: Terry Simons Date: Mon, 1 May 2017 16:51:57 -0700 Subject: [PATCH 2/7] Add requested change for PEP 469 compliance. --- usbinfo/darwin.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usbinfo/darwin.py b/usbinfo/darwin.py index 5701235..9d684a9 100755 --- a/usbinfo/darwin.py +++ b/usbinfo/darwin.py @@ -101,7 +101,7 @@ def _disk_partition(node): info = {} for child in node.get('IORegistryEntryChildren', []): - for class_name, handler in ioclass_handlers.items(): + for class_name, handler in iter(ioclass_handlers.items()): if child.get('IOObjectClass') == class_name: info.update(handler(child)) info.update(_extra_if_info(child)) From ac28a990dfe95f2ba24a288df776494cfcc27ebd Mon Sep 17 00:00:00 2001 From: Terry Simons Date: Mon, 1 May 2017 18:21:36 -0700 Subject: [PATCH 3/7] Patch for ST-Link serial number encoding bug. --- usbinfo/darwin.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/usbinfo/darwin.py b/usbinfo/darwin.py index 9d684a9..e6eba5b 100755 --- a/usbinfo/darwin.py +++ b/usbinfo/darwin.py @@ -18,6 +18,7 @@ import copy import platform +import re import subprocess from .posix import get_mounts @@ -30,6 +31,38 @@ OSX_VERSION_MICRO_INT = [int(part) for part in OSX_VERSION_STR.split('.')] +def _sanitize_xml(data): + pattern = re.compile(r'^(\s*?\)(.*?)(\<\/string\>.*?)$') + output = [] + + for i, line in enumerate(data.split('\n')): + chunk = line.decode('utf-8') + match = re.match(pattern, chunk) + if match: + start = match.group(1) + middle = match.group(2) + end = match.group(3) + needs_patch = False + # Inspect the line and see if it has invalid characters. + byte_list = bytearray([ord(byte) for byte in middle]) + for byte in byte_list: + if byte < 32: + needs_patch = True + if needs_patch: + middle = ''.join(['%02X' % byte for byte in byte_list]) + new_line = '{start}{middle}{end}'.format(start=start, + middle=middle, + end=end) + output.append(new_line) + else: + output.append(line) + else: + output.append(line) + output = '\n'.join(output) + + return output.encode('utf-8') + + def _ioreg_usb_devices(nodename=None): """Returns a list of USB device tree from ioreg""" import plistlib @@ -38,6 +71,10 @@ def _ioreg(nodename): """Run ioreg command on specific node name""" cmd = ['ioreg', '-a', '-l', '-r', '-n', nodename] output = subprocess.check_output(cmd) + # ST-Link devices (and possibly others?) erroneously store binary data + # in the serial number, which causes plistlib to blow up. + # This will convert that to hex and preserve contents otherwise. + output = _sanitize_xml(output) plist_data = [] if output: try: From 954e4bab4a05da3cfe516d2ef2e671867cfa12bc Mon Sep 17 00:00:00 2001 From: Terry Simons Date: Mon, 1 May 2017 20:00:57 -0700 Subject: [PATCH 4/7] Fix encoding issues with patch. --- usbinfo/darwin.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/usbinfo/darwin.py b/usbinfo/darwin.py index e6eba5b..5bb68c8 100755 --- a/usbinfo/darwin.py +++ b/usbinfo/darwin.py @@ -53,15 +53,16 @@ def _sanitize_xml(data): new_line = '{start}{middle}{end}'.format(start=start, middle=middle, end=end) - output.append(new_line) + output.append(new_line.encode('utf-8')) else: + # Already encoded. output.append(line) else: + # Already encoded output.append(line) output = '\n'.join(output) - return output.encode('utf-8') - + return output def _ioreg_usb_devices(nodename=None): """Returns a list of USB device tree from ioreg""" From f55514a323131a74f8a7ad220e6022dafb30d836 Mon Sep 17 00:00:00 2001 From: Terry Simons Date: Tue, 2 May 2017 10:28:34 -0700 Subject: [PATCH 5/7] Code review fixes. --- usbinfo/darwin.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/usbinfo/darwin.py b/usbinfo/darwin.py index 5bb68c8..95b6fab 100755 --- a/usbinfo/darwin.py +++ b/usbinfo/darwin.py @@ -30,14 +30,23 @@ OSX_VERSION_MINOR_INT, \ OSX_VERSION_MICRO_INT = [int(part) for part in OSX_VERSION_STR.split('.')] +sanitize_pattern = re.compile(r'^(\s*?\)(.*?)(\<\/string\>.*?)$') def _sanitize_xml(data): - pattern = re.compile(r'^(\s*?\)(.*?)(\<\/string\>.*?)$') + """Takes an plist (xml) and checks defintions for control characters. + + If a control character is found, the string is converted to hexidecimal. + For ST-Link devices, this properly displays the serial number, which + is eroneously encoded as binary data, which causes the plistlib XML parser + to crash. + + Returns the same document, with any mis-encoded values converted + to ascii hex.""" output = [] for i, line in enumerate(data.split('\n')): chunk = line.decode('utf-8') - match = re.match(pattern, chunk) + match = re.match(sanitize_pattern, chunk) if match: start = match.group(1) middle = match.group(2) From 339e7f9092799555df9a64031eb163c985a6bf27 Mon Sep 17 00:00:00 2001 From: Terry Simons Date: Fri, 5 May 2017 14:49:48 -0700 Subject: [PATCH 6/7] Fix xml sanitization for Python 3. --- usbinfo/darwin.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/usbinfo/darwin.py b/usbinfo/darwin.py index 95b6fab..9545c3e 100755 --- a/usbinfo/darwin.py +++ b/usbinfo/darwin.py @@ -44,8 +44,10 @@ def _sanitize_xml(data): to ascii hex.""" output = [] + data = data.decode('utf-8') + for i, line in enumerate(data.split('\n')): - chunk = line.decode('utf-8') + chunk = line match = re.match(sanitize_pattern, chunk) if match: start = match.group(1) @@ -62,16 +64,14 @@ def _sanitize_xml(data): new_line = '{start}{middle}{end}'.format(start=start, middle=middle, end=end) - output.append(new_line.encode('utf-8')) + output.append(new_line) else: - # Already encoded. output.append(line) else: - # Already encoded output.append(line) - output = '\n'.join(output) + output = '\n'.join([line for line in output]) - return output + return output.encode('utf-8') def _ioreg_usb_devices(nodename=None): """Returns a list of USB device tree from ioreg""" From 3e8b1177a4714a3a2b41fbc6f95073c1e3c4c259 Mon Sep 17 00:00:00 2001 From: Terry Simons Date: Tue, 26 Sep 2017 13:40:49 -0700 Subject: [PATCH 7/7] Fix High Sierra issue with version parsing. --- usbinfo/darwin.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/usbinfo/darwin.py b/usbinfo/darwin.py index 9545c3e..31bd1e1 100755 --- a/usbinfo/darwin.py +++ b/usbinfo/darwin.py @@ -26,9 +26,14 @@ # platform.mac_ver()'s first tuple element encodes the OS X version, # such as 10.11.3. OSX_VERSION_STR = platform.mac_ver()[0] -OSX_VERSION_MAJOR_INT, \ -OSX_VERSION_MINOR_INT, \ -OSX_VERSION_MICRO_INT = [int(part) for part in OSX_VERSION_STR.split('.')] +OSX_VERSION_INFO = [int(part) for part in OSX_VERSION_STR.split('.')] +OSX_VERSION_MAJOR_INT = OSX_VERSION_INFO[0] +OSX_VERSION_MINOR_INT = OSX_VERSION_INFO[1] +OSX_VERSION_MICRO_INT = 0 + +if len(OSX_VERSION_INFO) >= 3: + OSX_VERSION_MICRO_INT = OSX_VERSION_INFO[2] + sanitize_pattern = re.compile(r'^(\s*?\)(.*?)(\<\/string\>.*?)$')