From fb337f26c8e58ed0ce0750f7899ccbd5da203dee Mon Sep 17 00:00:00 2001 From: wendyisgr33n Date: Mon, 30 Jul 2018 10:43:57 -0700 Subject: [PATCH 1/5] Fixed AFC afc.pxi definitions for Python2/3 compatibility. Added missing public method 'remove_path_and_contents' --- cython/afc.pxi | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/cython/afc.pxi b/cython/afc.pxi index e34588f9..6bd81824 100644 --- a/cython/afc.pxi +++ b/cython/afc.pxi @@ -52,6 +52,7 @@ cdef extern from "libimobiledevice/afc.h": afc_error_t afc_read_directory(afc_client_t client, char *dir, char ***list) afc_error_t afc_get_file_info(afc_client_t client, char *filename, char ***infolist) afc_error_t afc_remove_path(afc_client_t client, char *path) + afc_error_t afc_remove_path_and_contents(afc_client_t client, char *path) afc_error_t afc_rename_path(afc_client_t client, char *f, char *to) afc_error_t afc_make_directory(afc_client_t client, char *dir) afc_error_t afc_truncate(afc_client_t client, char *path, uint64_t newsize) @@ -235,17 +236,17 @@ cdef class AfcClient(BaseService): afc_file_mode_t c_mode uint64_t handle AfcFile f - if mode == 'r': + if mode == b'r': c_mode = AFC_FOPEN_RDONLY - elif mode == 'r+': + elif mode == b'r+': c_mode = AFC_FOPEN_RW - elif mode == 'w': + elif mode == b'w': c_mode = AFC_FOPEN_WRONLY - elif mode == 'w+': + elif mode == b'w+': c_mode = AFC_FOPEN_WR - elif mode == 'a': + elif mode == b'a': c_mode = AFC_FOPEN_APPEND - elif mode == 'a+': + elif mode == b'a+': c_mode = AFC_FOPEN_RDAPPEND else: raise ValueError("mode string must be 'r', 'r+', 'w', 'w+', 'a', or 'a+'") @@ -282,6 +283,9 @@ cdef class AfcClient(BaseService): cpdef remove_path(self, bytes path): self.handle_error(afc_remove_path(self._c_client, path)) + cpdef remove_path_and_contents(self, bytes path): + self.handle_error(afc_remove_path_and_contents(self._c_client, path)) + cpdef rename_path(self, bytes f, bytes t): self.handle_error(afc_rename_path(self._c_client, f, t)) @@ -308,17 +312,17 @@ cdef class Afc2Client(AfcClient): afc_file_mode_t c_mode uint64_t handle AfcFile f - if mode == 'r': + if mode == b'r': c_mode = AFC_FOPEN_RDONLY - elif mode == 'r+': + elif mode == b'r+': c_mode = AFC_FOPEN_RW - elif mode == 'w': + elif mode == b'w': c_mode = AFC_FOPEN_WRONLY - elif mode == 'w+': + elif mode == b'w+': c_mode = AFC_FOPEN_WR - elif mode == 'a': + elif mode == b'a': c_mode = AFC_FOPEN_APPEND - elif mode == 'a+': + elif mode == b'a+': c_mode = AFC_FOPEN_RDAPPEND else: raise ValueError("mode string must be 'r', 'r+', 'w', 'w+', 'a', or 'a+'") From b71e8935949a1d6f419a3f783d804809fb4c309b Mon Sep 17 00:00:00 2001 From: wendyisgr33n Date: Mon, 30 Jul 2018 10:44:40 -0700 Subject: [PATCH 2/5] Fixed debugserver.pxi PyString_AsString compatibility with Python3 --- cython/debugserver.pxi | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cython/debugserver.pxi b/cython/debugserver.pxi index ddbe0667..c28a40b2 100644 --- a/cython/debugserver.pxi +++ b/cython/debugserver.pxi @@ -44,7 +44,12 @@ cdef class DebugServerError(BaseError): # from http://stackoverflow.com/a/17511714 -from cpython.string cimport PyString_AsString +# https://github.com/libimobiledevice/libimobiledevice/pull/198 +from cpython cimport PY_MAJOR_VERSION +if PY_MAJOR_VERSION <= 2: + from cpython.string cimport PyString_AsString +else: + from cpython.bytes cimport PyBytes_AsString as PyString_AsString cdef char ** to_cstring_array(list_str): if not list_str: return NULL From 44f54cdc0ebb052e4a642023bbf96504e6139ec9 Mon Sep 17 00:00:00 2001 From: wendyisgr33n Date: Mon, 30 Jul 2018 10:45:22 -0700 Subject: [PATCH 3/5] Fixed bytes/strings check in imobiledevice.pyx for compatibility with Python2/3 --- cython/imobiledevice.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cython/imobiledevice.pyx b/cython/imobiledevice.pyx index bc861b33..24a5201f 100644 --- a/cython/imobiledevice.pyx +++ b/cython/imobiledevice.pyx @@ -171,7 +171,7 @@ from libc.stdlib cimport * cdef class iDevice(Base): def __cinit__(self, object udid=None, *args, **kwargs): cdef char* c_udid = NULL - if isinstance(udid, basestring): + if isinstance(udid, (str, bytes)): c_udid = udid elif udid is not None: raise TypeError("iDevice's constructor takes a string or None as the udid argument") From 8908619973e751b778d3fb73dc309cd5cb7f4122 Mon Sep 17 00:00:00 2001 From: wendyisgr33n Date: Mon, 30 Jul 2018 10:45:55 -0700 Subject: [PATCH 4/5] Fixed bytes/strings checks in lockdown.pxi for compatibility with Python2/3 --- cython/lockdown.pxi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cython/lockdown.pxi b/cython/lockdown.pxi index f2490497..1bf7072e 100644 --- a/cython/lockdown.pxi +++ b/cython/lockdown.pxi @@ -230,9 +230,9 @@ cdef class LockdownClient(PropertyListService): if issubclass(service, BaseService) and \ service.__service_name__ is not None \ - and isinstance(service.__service_name__, basestring): + and isinstance(service.__service_name__, (str, bytes)): c_service_name = service.__service_name__ - elif isinstance(service, basestring): + elif isinstance(service, (str, bytes)): c_service_name = service else: raise TypeError("LockdownClient.start_service() takes a BaseService or string as its first argument") @@ -253,7 +253,7 @@ cdef class LockdownClient(PropertyListService): if not hasattr(service_class, '__service_name__') and \ not service_class.__service_name__ is not None \ - and not isinstance(service_class.__service_name__, basestring): + and not isinstance(service_class.__service_name__, (str, bytes)): raise TypeError("LockdownClient.get_service_client() takes a BaseService as its first argument") descriptor = self.start_service(service_class) From e59cbdbf4e7dba98ef57a54e314a89edfea0a3dc Mon Sep 17 00:00:00 2001 From: wendyisgr33n Date: Mon, 30 Jul 2018 10:47:48 -0700 Subject: [PATCH 5/5] Fixed method visibility in mobilebackup2.pxi API --- cython/mobilebackup2.pxi | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/cython/mobilebackup2.pxi b/cython/mobilebackup2.pxi index aac53589..56483ced 100644 --- a/cython/mobilebackup2.pxi +++ b/cython/mobilebackup2.pxi @@ -54,10 +54,10 @@ cdef class MobileBackup2Client(PropertyListService): cdef inline BaseError _error(self, int16_t ret): return MobileBackup2Error(ret) - cdef send_message(self, bytes message, plist.Node options): + cpdef send_message(self, bytes message, plist.Node options): self.handle_error(mobilebackup2_send_message(self._c_client, message, options._c_node)) - cdef tuple receive_message(self): + cpdef tuple receive_message(self): cdef: char* dlmessage = NULL plist.plist_t c_node = NULL @@ -73,29 +73,34 @@ cdef class MobileBackup2Client(PropertyListService): free(dlmessage) raise - cdef int send_raw(self, bytes data, int length): + cpdef int send_raw(self, bytes data, int length): cdef: - uint32_t bytes = 0 + uint32_t bytes_recvd = 0 mobilebackup2_error_t err - err = mobilebackup2_send_raw(self._c_client, data, length, &bytes) + err = mobilebackup2_send_raw(self._c_client, data, length, &bytes_recvd) try: self.handle_error(err) - return bytes + return bytes_recvd except BaseError, e: raise - cdef int receive_raw(self, bytes data, int length): + cpdef int receive_raw(self, bytearray data, int length): cdef: - uint32_t bytes = 0 + uint32_t bytes_recvd = 0 mobilebackup2_error_t err - err = mobilebackup2_receive_raw(self._c_client, data, length, &bytes) + err = mobilebackup2_receive_raw(self._c_client, data, length, &bytes_recvd) + + # Throwing an exception when we test if theres more data to read is excessive + if err == -1 and bytes_recvd == 0: + return 0 + try: self.handle_error(err) - return bytes + return bytes_recvd except BaseError, e: raise - cdef float version_exchange(self, double[::1] local_versions): + cpdef float version_exchange(self, double[::1] local_versions): cdef: double[::1] temp = None double remote_version = 0.0 @@ -107,8 +112,8 @@ cdef class MobileBackup2Client(PropertyListService): except BaseError, e: raise - cdef send_request(self, bytes request, bytes target_identifier, bytes source_identifier, plist.Node options): + cpdef send_request(self, bytes request, bytes target_identifier, bytes source_identifier, plist.Node options): self.handle_error(mobilebackup2_send_request(self._c_client, request, target_identifier, source_identifier, options._c_node)) - cdef send_status_response(self, int status_code, bytes status1, plist.Node status2): + cpdef send_status_response(self, int status_code, bytes status1, plist.Node status2): self.handle_error(mobilebackup2_send_status_response(self._c_client, status_code, status1, status2._c_node)) From 900cc8c1d6cba31cd574a9b71d333fc21bdac1f4 Mon Sep 17 00:00:00 2001 From: aymenim Date: Tue, 15 Mar 2016 23:56:08 +0300 Subject: [PATCH 1/2] cython: fixed notification_proxy callback gil lock cython notification proxy bug segmentation fault when callback called without gil --- cython/notification_proxy.pxi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cython/notification_proxy.pxi b/cython/notification_proxy.pxi index 4ffbf074..203c7835 100644 --- a/cython/notification_proxy.pxi +++ b/cython/notification_proxy.pxi @@ -70,7 +70,7 @@ NP_ITDBPREP_DID_END = C_NP_ITDBPREP_DID_END NP_LANGUAGE_CHANGED = C_NP_LANGUAGE_CHANGED NP_ADDRESS_BOOK_PREF_CHANGED = C_NP_ADDRESS_BOOK_PREF_CHANGED -cdef void np_notify_cb(const_char_ptr notification, void *py_callback): +cdef void np_notify_cb(const_char_ptr notification, void *py_callback) with gil: (py_callback)(notification) cdef class NotificationProxyError(BaseError): From 62f8903a024f96040d0f7f0658ba4722389b3169 Mon Sep 17 00:00:00 2001 From: aymenim Date: Mon, 21 Mar 2016 11:27:26 +0300 Subject: [PATCH 2/2] cython binding passing null to lockdown set value * added code to handle passing null values to lockdown_set_value, needed for example setting device name . --- cython/lockdown.pxi | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/cython/lockdown.pxi b/cython/lockdown.pxi index c8d511eb..e4f76084 100644 --- a/cython/lockdown.pxi +++ b/cython/lockdown.pxi @@ -210,14 +210,23 @@ cdef class LockdownClient(PropertyListService): raise cpdef set_value(self, bytes domain, bytes key, object value): - cdef plist.plist_t c_node = plist.native_to_plist_t(value) + cdef: + plist.plist_t c_node = NULL + char* c_domain = NULL + char* c_key = NULL + + c_node = plist.native_to_plist_t(value) + if domain is not None: + c_domain = domain + if key is not None: + c_key = key try: - self.handle_error(lockdownd_set_value(self._c_client, domain, key, c_node)) + self.handle_error(lockdownd_set_value(self._c_client, c_domain, c_key, c_node)) except BaseError, e: raise finally: if c_node != NULL: - plist.plist_free(c_node) + c_node = NULL cpdef remove_value(self, bytes domain, bytes key): self.handle_error(lockdownd_remove_value(self._c_client, domain, key))