From 67fcf8a2754c6fa604ad67ffa232903a89ddbef2 Mon Sep 17 00:00:00 2001 From: Ihor Dutchak Date: Sun, 7 Apr 2024 16:55:30 +0300 Subject: [PATCH] Squashed 'libusb/' changes from 5c64e52..43107c8 43107c8 darwin: Suppress false positive warning with an assert 1c1bad9 darwin: Fix clang static analyzer warning about a variable that's never read 4e246a7 xcode: Enable several additional warnings in the Xcode project d81e80a darwin: Correct interpretation of COM-style Release() return value a07ecfe Fix most warnings about implicit sign conversion 288d82f xusb: Avoid warning about implicit switch fallthrough 233a8de emscripten: Remove superfluous capability 6c0ae1a hotplug_exit: Mutex protection of context device list while cleaning it 51d2c0f hotplug_exit: Remove parents recursively 6cf58ba Add clang-tidy config file git-subtree-dir: libusb git-subtree-split: 43107c84e4a5f6b15c296eff8cc3578100f35dce --- .clang-tidy | 47 +++++++++++++++++++++++++ Xcode/common.xcconfig | 20 +++++++++++ examples/xusb.c | 35 +++++++++++-------- libusb/core.c | 6 ++-- libusb/descriptor.c | 8 ++--- libusb/hotplug.c | 35 ++++++++++++++----- libusb/io.c | 1 + libusb/os/darwin_usb.c | 61 ++++++++++++++++++--------------- libusb/os/emscripten_webusb.cpp | 2 +- libusb/sync.c | 13 ++++--- libusb/version_nano.h | 2 +- tests/macos.c | 4 +-- 12 files changed, 168 insertions(+), 66 deletions(-) create mode 100644 .clang-tidy diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..6349aa8 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,47 @@ +--- +Checks: "-*,\ +boost-*,\ +bugprone-*,\ +-bugprone-assignment-in-if-condition,\ +-bugprone-branch-clone,\ +-bugprone-easily-swappable-parameters,\ +-bugprone-implicit-widening-of-multiplication-result,\ +-bugprone-macro-parentheses,\ +-bugprone-misplaced-widening-cast,\ +-bugprone-narrowing-conversions,\ +-bugprone-reserved-identifier,\ +-bugprone-signed-char-misuse,\ +-bugprone-suspicious-string-compare,\ +-bugprone-switch-missing-default-case,\ +-bugprone-unsafe-functions,\ +-bugprone-too-small-loop-variable,\ +clang-analyzer-*,\ +-clang-analyzer-core.NullDereference,\ +-clang-analyzer-deadcode.DeadStores,\ +-clang-analyzer-optin.portability.UnixAPI,\ +-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,\ +-clang-analyzer-security.insecureAPI.strcpy,\ +-clang-analyzer-unix.Malloc,\ +misc-*,\ +-misc-no-recursion,\ +-misc-include-cleaner,\ +modernize-*,\ +-modernize-macro-to-enum,\ +performance-*,\ +-performance-no-int-to-ptr,\ +-performance-type-promotion-in-math-fn,\ +portability-*,\ +readability-*,\ +-readability-braces-around-statements,\ +-readability-else-after-return,\ +-readability-identifier-length,\ +-readability-function-cognitive-complexity,\ +-readability-inconsistent-declaration-parameter-name,\ +-readability-isolate-declaration,\ +-readability-magic-numbers,\ +-readability-non-const-parameter,\ +-readability-uppercase-literal-suffix,\ +-readability-misleading-indentation,\ +" +#WarningsAsErrors: "*" +... diff --git a/Xcode/common.xcconfig b/Xcode/common.xcconfig index 06108ad..6751445 100644 --- a/Xcode/common.xcconfig +++ b/Xcode/common.xcconfig @@ -65,6 +65,26 @@ CLANG_WARN_INT_CONVERSION = YES CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES CLANG_WARN_STRICT_PROTOTYPES = YES CLANG_WARN_SUSPICIOUS_IMPLICIT_CONVERSION = YES +CLANG_WARN_COMPLETION_HANDLER_MISUSE = YES +CLANG_WARN_IMPLICIT_FALLTHROUGH = YES +CLANG_WARN_FRAMEWORK_INCLUDE_PRIVATE_FROM_PUBLIC = YES +CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES +CLANG_WARN_SEMICOLON_BEFORE_METHOD_BODY = YES +GCC_WARN_SIGN_COMPARE = YES +CLANG_WARN__EXIT_TIME_DESTRUCTORS = YES +GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES +GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES +CLANG_WARN_ATOMIC_IMPLICIT_SEQ_CST = YES +CLANG_WARN_OBJC_IMPLICIT_ATOMIC_PROPERTIES = YES +CLANG_WARN_OBJC_INTERFACE_IVARS = YES +GCC_WARN_STRICT_SELECTOR_MATCH = YES +CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES +CLANG_WARN_UNREACHABLE_CODE = YES +CLANG_WARN_RANGE_LOOP_ANALYSIS = YES +CLANG_WARN_SUSPICIOUS_MOVE = YES +CLANG_WARN__DUPLICATE_METHOD_MATCH = YES +CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES +GCC_WARN_UNDECLARED_SELECTOR = YES // Static analyzer warnings. CLANG_ANALYZER_NONNULL = YES diff --git a/examples/xusb.c b/examples/xusb.c index 239450c..502ff14 100644 --- a/examples/xusb.c +++ b/examples/xusb.c @@ -461,7 +461,7 @@ static int test_mass_storage(libusb_device_handle *handle, uint8_t endpoint_in, double device_size; uint8_t cdb[16]; // SCSI Command Descriptor Block uint8_t buffer[64]; - char vid[9], pid[9], rev[5]; + unsigned char vid[9], pid[9], rev[5]; unsigned char *data; FILE *fd; @@ -560,7 +560,7 @@ static int get_hid_record_size(uint8_t *hid_report_descriptor, int size, int typ uint8_t i, j = 0; uint8_t offset; int record_size[3] = {0, 0, 0}; - int nb_bits = 0, nb_items = 0; + unsigned int nb_bits = 0, nb_items = 0; bool found_record_marker; found_record_marker = false; @@ -575,7 +575,7 @@ static int get_hid_record_size(uint8_t *hid_report_descriptor, int size, int typ case 0x94: // count nb_items = 0; for (j=1; j UINT16_MAX) { + printf("\nSkipping Feature Report readout (bigger than UINT16_MAX)\n"); } else { - report_buffer = (uint8_t*) calloc(size, 1); + report_buffer = (uint8_t*) calloc(1, (size_t)size); if (report_buffer == NULL) { return -1; } @@ -644,7 +646,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t endpoint_in) r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|0, 0, report_buffer, (uint16_t)size, 5000); if (r >= 0) { - display_buffer_hex(report_buffer, size); + display_buffer_hex(report_buffer, (unsigned int)size); } else { switch(r) { case LIBUSB_ERROR_NOT_FOUND: @@ -665,8 +667,10 @@ static int test_hid(libusb_device_handle *handle, uint8_t endpoint_in) size = get_hid_record_size(hid_report_descriptor, descriptor_size, HID_REPORT_TYPE_INPUT); if (size <= 0) { printf("\nSkipping Input Report readout (None detected)\n"); + } else if (size > UINT16_MAX) { + printf("\nSkipping Input Report readout (bigger than UINT16_MAX)\n"); } else { - report_buffer = (uint8_t*) calloc(size, 1); + report_buffer = (uint8_t*) calloc(1, (size_t)size); if (report_buffer == NULL) { return -1; } @@ -675,7 +679,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t endpoint_in) r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE, HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, 0, report_buffer, (uint16_t)size, 5000); if (r >= 0) { - display_buffer_hex(report_buffer, size); + display_buffer_hex(report_buffer, (unsigned int)size); } else { switch(r) { case LIBUSB_ERROR_TIMEOUT: @@ -695,7 +699,7 @@ static int test_hid(libusb_device_handle *handle, uint8_t endpoint_in) printf("\nTesting interrupt read using endpoint %02X...\n", endpoint_in); r = libusb_interrupt_transfer(handle, endpoint_in, report_buffer, size, &size, 5000); if (r >= 0) { - display_buffer_hex(report_buffer, size); + display_buffer_hex(report_buffer, (unsigned int)size); } else { printf(" %s\n", libusb_strerror((enum libusb_error)r)); } @@ -753,7 +757,7 @@ static void read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uin perr(" Failed: %s", libusb_strerror((enum libusb_error)r)); return; } else { - display_buffer_hex(os_desc, r); + display_buffer_hex(os_desc, (unsigned int)r); } } } @@ -824,7 +828,7 @@ static int test_device(uint16_t vid, uint16_t pid) struct libusb_device_descriptor dev_desc; const char* const speed_name[6] = { "Unknown", "1.5 Mbit/s (USB LowSpeed)", "12 Mbit/s (USB FullSpeed)", "480 Mbit/s (USB HighSpeed)", "5000 Mbit/s (USB SuperSpeed)", "10000 Mbit/s (USB SuperSpeedPlus)" }; - char string[128]; + unsigned char string[128]; uint8_t string_index[3]; // indexes of the string descriptors uint8_t endpoint_in = 0, endpoint_out = 0; // default IN and OUT endpoints @@ -960,13 +964,13 @@ static int test_device(uint16_t vid, uint16_t pid) if (string_index[i] == 0) { continue; } - if (libusb_get_string_descriptor_ascii(handle, string_index[i], (unsigned char*)string, sizeof(string)) > 0) { + if (libusb_get_string_descriptor_ascii(handle, string_index[i], string, sizeof(string)) > 0) { printf(" String (0x%02X): \"%s\"\n", string_index[i], string); } } printf("\nReading OS string descriptor:"); - r = libusb_get_string_descriptor(handle, MS_OS_DESC_STRING_INDEX, 0, (unsigned char*)string, MS_OS_DESC_STRING_LENGTH); + r = libusb_get_string_descriptor(handle, MS_OS_DESC_STRING_INDEX, 0, string, MS_OS_DESC_STRING_LENGTH); if (r == MS_OS_DESC_STRING_LENGTH && memcmp(ms_os_desc_string, string, sizeof(ms_os_desc_string)) == 0) { // If this is a Microsoft OS String Descriptor, // attempt to read the WinUSB extended Feature Descriptors @@ -991,7 +995,7 @@ static int test_device(uint16_t vid, uint16_t pid) printf(" bFunctionSubClass: %02X\n", iad->bFunctionSubClass); printf(" bFunctionProtocol: %02X\n", iad->bFunctionProtocol); if (iad->iFunction) { - if (libusb_get_string_descriptor_ascii(handle, iad->iFunction, (unsigned char*)string, sizeof(string)) > 0) + if (libusb_get_string_descriptor_ascii(handle, iad->iFunction, string, sizeof(string)) > 0) printf(" iFunction: %u (%s)\n", iad->iFunction, string); else printf(" iFunction: %u (libusb_get_string_descriptor_ascii failed!)\n", iad->iFunction); @@ -1017,6 +1021,7 @@ static int test_device(uint16_t vid, uint16_t pid) break; case USE_SCSI: CALL_CHECK_CLOSE(test_mass_storage(handle, endpoint_in, endpoint_out), handle); + break; case USE_GENERIC: break; } diff --git a/libusb/core.c b/libusb/core.c index ffe33b7..bdfc77c 100644 --- a/libusb/core.c +++ b/libusb/core.c @@ -964,7 +964,7 @@ int API_EXPORTED libusb_get_port_numbers(libusb_device *dev, dev = dev->parent_dev; } if (i < port_numbers_len) - memmove(port_numbers, &port_numbers[i], port_numbers_len - i); + memmove(port_numbers, &port_numbers[i], (size_t)(port_numbers_len - i)); return port_numbers_len - i; } @@ -1014,7 +1014,7 @@ uint8_t API_EXPORTED libusb_get_device_address(libusb_device *dev) */ int API_EXPORTED libusb_get_device_speed(libusb_device *dev) { - return dev->speed; + return (int)(dev->speed); } static const struct libusb_endpoint_descriptor *find_endpoint( @@ -2456,7 +2456,7 @@ int API_EXPORTED libusb_init_context(libusb_context **ctx, const struct libusb_i _ctx->debug = get_env_debug_level(); _ctx->debug_fixed = 1; } else if (default_context_options[LIBUSB_OPTION_LOG_LEVEL].is_set) { - _ctx->debug = default_context_options[LIBUSB_OPTION_LOG_LEVEL].arg.ival; + _ctx->debug = (enum libusb_log_level)default_context_options[LIBUSB_OPTION_LOG_LEVEL].arg.ival; } #endif diff --git a/libusb/descriptor.c b/libusb/descriptor.c index 4623ad1..84055fe 100644 --- a/libusb/descriptor.c +++ b/libusb/descriptor.c @@ -156,7 +156,7 @@ static int parse_endpoint(struct libusb_context *ctx, if (!extra) return LIBUSB_ERROR_NO_MEM; - memcpy(extra, begin, len); + memcpy(extra, begin, (size_t)len); endpoint->extra = extra; endpoint->extra_length = len; @@ -286,7 +286,7 @@ static int parse_interface(libusb_context *ctx, goto err; } - memcpy(extra, begin, len); + memcpy(extra, begin, (size_t)len); ifp->extra = extra; ifp->extra_length = len; } @@ -431,7 +431,7 @@ static int parse_configuration(struct libusb_context *ctx, goto err; } - memcpy(extra + config->extra_length, begin, len); + memcpy(extra + config->extra_length, begin, (size_t)len); config->extra = extra; config->extra_length += len; } @@ -1241,7 +1241,7 @@ static int parse_iad_array(struct libusb_context *ctx, iad_array->iad = NULL; if (iad_array->length > 0) { - iad = calloc(iad_array->length, sizeof(*iad)); + iad = calloc((size_t)iad_array->length, sizeof(*iad)); if (!iad) return LIBUSB_ERROR_NO_MEM; diff --git a/libusb/hotplug.c b/libusb/hotplug.c index 3c64f69..026e11d 100644 --- a/libusb/hotplug.c +++ b/libusb/hotplug.c @@ -161,6 +161,27 @@ void usbi_hotplug_init(struct libusb_context *ctx) usbi_atomic_store(&ctx->hotplug_ready, 1); } +static void usbi_recursively_remove_parents(struct libusb_device *dev, struct libusb_device *next_dev) +{ + if (dev && dev->parent_dev) { + if (usbi_atomic_load(&dev->parent_dev->refcnt) == 1) { + /* The parent was processed before this device in the list and + * therefore has its ref count already decremented for its own ref. + * The only remaining counted ref comes from its remaining single child. + * It will thus be released when its child will be released. So we + * can remove it from the list. This is safe as parent_dev cannot be + * equal to next_dev given that we know at this point that it was + * previously seen in the list. */ + assert (dev->parent_dev != next_dev); + if (dev->parent_dev->list.next && dev->parent_dev->list.prev) { + list_del(&dev->parent_dev->list); + } + } + + usbi_recursively_remove_parents(dev->parent_dev, next_dev); + } +} + void usbi_hotplug_exit(struct libusb_context *ctx) { struct usbi_hotplug_callback *hotplug_cb, *next_cb; @@ -193,7 +214,8 @@ void usbi_hotplug_exit(struct libusb_context *ctx) free(msg); } - /* free all discovered devices. due to parent references loop until no devices are freed. */ + usbi_mutex_lock(&ctx->usb_devs_lock); /* hotplug thread might still be processing an already triggered event, possibly accessing this list as well */ + /* free all discovered devices */ for_each_device_safe(ctx, dev, next_dev) { /* remove the device from the usb_devs list only if there are no * references held, otherwise leave it on the list so that a @@ -201,15 +223,12 @@ void usbi_hotplug_exit(struct libusb_context *ctx) if (usbi_atomic_load(&dev->refcnt) == 1) { list_del(&dev->list); } - if (dev->parent_dev && usbi_atomic_load(&dev->parent_dev->refcnt) == 1) { - /* the parent was before this device in the list and will be released. - remove it from the list. this is safe as parent_dev can not be - equal to next_dev. */ - assert (dev->parent_dev != next_dev); - list_del(&dev->parent_dev->list); - } + + usbi_recursively_remove_parents(dev, next_dev); + libusb_unref_device(dev); } + usbi_mutex_unlock(&ctx->usb_devs_lock); usbi_mutex_destroy(&ctx->hotplug_cbs_lock); } diff --git a/libusb/io.c b/libusb/io.c index ab84ba6..0b2aaf6 100644 --- a/libusb/io.c +++ b/libusb/io.c @@ -1714,6 +1714,7 @@ int usbi_handle_transfer_completion(struct usbi_transfer *itransfer, flags = transfer->flags; transfer->status = status; transfer->actual_length = itransfer->transferred; + assert(transfer->actual_length >= 0); usbi_dbg(ctx, "transfer %p has callback %p", (void *) transfer, transfer->callback); if (transfer->callback) { diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c index c0963e0..bcfa3ca 100644 --- a/libusb/os/darwin_usb.c +++ b/libusb/os/darwin_usb.c @@ -40,7 +40,7 @@ /* Default timeout to 10s for reenumerate. This is needed because USBDeviceReEnumerate * does not return error status on macOS. */ -#define DARWIN_REENUMERATE_TIMEOUT_US (10 * USEC_PER_SEC) +#define DARWIN_REENUMERATE_TIMEOUT_US (10ULL * USEC_PER_SEC) #include #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 && MAC_OS_X_VERSION_MIN_REQUIRED < 101200 @@ -70,8 +70,8 @@ static struct list_head darwin_cached_devices; static const char *darwin_device_class = "IOUSBDevice"; uint32_t libusb_testonly_fake_running_version __attribute__ ((visibility ("hidden"))); -int libusb_testonly_using_running_interface_version __attribute__ ((visibility ("hidden"))); -int libusb_testonly_using_running_device_version __attribute__ ((visibility ("hidden"))); +uint32_t libusb_testonly_using_running_interface_version __attribute__ ((visibility ("hidden"))); +uint32_t libusb_testonly_using_running_device_version __attribute__ ((visibility ("hidden"))); bool libusb_testonly_clear_running_version_cache __attribute__ ((visibility ("hidden"))); #define DARWIN_CACHED_DEVICE(a) (((struct darwin_device_priv *)usbi_get_device_priv((a)))->dev) @@ -173,7 +173,7 @@ static CFUUIDRef get_interface_interface_id(void) { return get_interface_interface()->interface_id; } -static int get_interface_interface_version(void) { +static uint32_t get_interface_interface_version(void) { return get_interface_interface()->version; } @@ -244,7 +244,7 @@ static CFUUIDRef get_device_interface_id(void) { return get_device_interface()->interface_id; } -static int get_device_interface_version(void) { +static uint32_t get_device_interface_version(void) { return get_device_interface()->version; } @@ -370,11 +370,11 @@ uint32_t get_running_version(void) { * it provides the exact macOS version instead of the approximate version (as below). */ ret = sysctlbyname("kern.osproductversion", os_version_string, &os_version_string_len, NULL, 0); if (ret == 0) { - int major = 10, minor = 0, patch = 0; - ret = sscanf(os_version_string, "%i.%i.%i", &major, &minor, &patch); + unsigned int major = 10, minor = 0, patch = 0; + ret = sscanf(os_version_string, "%u.%u.%u", &major, &minor, &patch); if (ret < 2) { usbi_err (NULL, "could not determine the running OS version, assuming 10.0, kern.osproductversion=%s", os_version_string); - return 100000; + return 10 * 10000; } return (major * 10000) + (minor * 100) + patch; } @@ -386,17 +386,17 @@ uint32_t get_running_version(void) { ret = sysctlbyname("kern.osrelease", os_release_string, &os_release_string_len, NULL, 0); if (ret != 0) { usbi_err (NULL, "could not read kern.osrelease, errno=", errno); - return 100000; + return 10 * 10000; } - int darwin_major = 1, darwin_minor = 0; - ret = sscanf(os_release_string, "%i.%i", &darwin_major, &darwin_minor); + unsigned int darwin_major = 1, darwin_minor = 0; + ret = sscanf(os_release_string, "%u.%u", &darwin_major, &darwin_minor); if (ret < 1) { usbi_err (NULL, "could not determine the running Darwin version, assuming 1.3 (OS X 10.0), kern.osrelease=%s", os_release_string); - return 100000; + return 10 * 10000; } - int major = 10, minor = 0, patch = 0; + unsigned int major = 10, minor = 0, patch = 0; if (1 == darwin_major && darwin_minor < 4) { /* 10.0.x */ @@ -1242,17 +1242,18 @@ static bool get_device_port (io_service_t service, UInt8 *port) { /* Returns 1 on success, 0 on failure. */ static bool get_device_parent_sessionID(io_service_t service, UInt64 *parent_sessionID) { - IOReturn kresult; - io_service_t parent; - /* Walk up the tree in the IOService plane until we find a parent that has a sessionID */ - parent = service; - while((kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent)) == kIOReturnSuccess) { + io_service_t parent = service; + do { + IOReturn kresult = IORegistryEntryGetParentEntry (parent, kIOUSBPlane, &parent); + if (kresult != kIOReturnSuccess) { + break; + } if (get_ioregistry_value_number (parent, CFSTR("sessionID"), kCFNumberSInt64Type, parent_sessionID)) { /* Success */ return true; } - } + } while (true); /* We ran out of parents */ return false; @@ -1361,6 +1362,8 @@ static enum libusb_error darwin_get_cached_device(struct libusb_context *ctx, io usbi_mutex_unlock(&darwin_cached_devices_mutex); + assert((ret == LIBUSB_SUCCESS) ? (*cached_out != NULL) : true); + return ret; } @@ -1471,6 +1474,7 @@ static enum libusb_error darwin_scan_devices(struct libusb_context *ctx) { while ((service = IOIteratorNext (deviceIterator))) { ret = darwin_get_cached_device (ctx, service, &cached_device, &old_session_id); + assert((ret >= 0) ? (cached_device != NULL) : true); if (ret < 0 || !cached_device->can_enumerate) { continue; } @@ -1868,9 +1872,10 @@ static int darwin_release_interface(struct libusb_device_handle *dev_handle, uin if (kresult != kIOReturnSuccess) usbi_warn (HANDLE_CTX (dev_handle), "USBInterfaceClose: %s", darwin_error_str(kresult)); - kresult = (*IOINTERFACE(cInterface))->Release(IOINTERFACE(cInterface)); - if (kresult != kIOReturnSuccess) - usbi_warn (HANDLE_CTX (dev_handle), "Release: %s", darwin_error_str(kresult)); + ULONG refCount = (*IOINTERFACE(cInterface))->Release(IOINTERFACE(cInterface)); + if (refCount != 0) { + usbi_warn (HANDLE_CTX (dev_handle), "Release final refCount: %u", refCount); + } IOINTERFACE(cInterface) = NULL; @@ -1972,7 +1977,7 @@ static int darwin_clear_halt(struct libusb_device_handle *dev_handle, unsigned c return darwin_to_libusb (kresult); } -static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t active_config, +static int darwin_restore_state (struct libusb_device_handle *dev_handle, uint8_t active_config, unsigned long claimed_interfaces) { struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); struct darwin_device_handle_priv *priv = usbi_get_device_handle_priv(dev_handle); @@ -2037,7 +2042,7 @@ static int darwin_restore_state (struct libusb_device_handle *dev_handle, int8_t static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, bool capture) { struct darwin_cached_device *dpriv = DARWIN_CACHED_DEVICE(dev_handle->dev); unsigned long claimed_interfaces = dev_handle->claimed_interfaces; - int8_t active_config = dpriv->active_config; + uint8_t active_config = dpriv->active_config; UInt32 options = 0; IOUSBDeviceDescriptor descriptor; IOUSBConfigurationDescriptorPtr cached_configuration; @@ -2100,8 +2105,10 @@ static int darwin_reenumerate_device (struct libusb_device_handle *dev_handle, b struct timespec now; usbi_get_monotonic_time(&now); - unsigned long elapsed_us = (now.tv_sec - start.tv_sec) * USEC_PER_SEC + - (now.tv_nsec - start.tv_nsec) / 1000; + long delta_sec = now.tv_sec - start.tv_sec; + long delta_nsec = now.tv_nsec - start.tv_nsec; + unsigned long long elapsed_us = (unsigned long long)delta_sec * USEC_PER_SEC + + (unsigned long long)delta_nsec / 1000ULL; if (elapsed_us >= DARWIN_REENUMERATE_TIMEOUT_US) { usbi_err (ctx, "darwin/reenumerate_device: timeout waiting for reenumerate"); @@ -2150,7 +2157,7 @@ static int darwin_reset_device (struct libusb_device_handle *dev_handle) { ret = darwin_reenumerate_device (dev_handle, false); if ((ret == LIBUSB_SUCCESS || ret == LIBUSB_ERROR_NOT_FOUND) && dpriv->capture_count > 0) { int capture_count; - int8_t active_config = dpriv->active_config; + uint8_t active_config = dpriv->active_config; unsigned long claimed_interfaces = dev_handle->claimed_interfaces; /* save old capture_count */ diff --git a/libusb/os/emscripten_webusb.cpp b/libusb/os/emscripten_webusb.cpp index f19c1bd..ced9ad8 100644 --- a/libusb/os/emscripten_webusb.cpp +++ b/libusb/os/emscripten_webusb.cpp @@ -844,7 +844,7 @@ int em_handle_transfer_completion(usbi_transfer* itransfer) { #pragma clang diagnostic ignored "-Wmissing-field-initializers" extern "C" const usbi_os_backend usbi_backend = { .name = "Emscripten + WebUSB backend", - .caps = LIBUSB_CAP_HAS_CAPABILITY, + .caps = 0, .get_device_list = em_get_device_list, .open = em_open, .close = em_close, diff --git a/libusb/sync.c b/libusb/sync.c index 146cce2..733927d 100644 --- a/libusb/sync.c +++ b/libusb/sync.c @@ -22,6 +22,7 @@ #include "libusbi.h" +#include #include /** @@ -139,7 +140,7 @@ int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle, if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) memcpy(data, libusb_control_transfer_get_data(transfer), - transfer->actual_length); + (size_t)transfer->actual_length); switch (transfer->status) { case LIBUSB_TRANSFER_COMPLETED: @@ -198,8 +199,10 @@ static int do_sync_bulk_transfer(struct libusb_device_handle *dev_handle, sync_transfer_wait_for_completion(transfer); - if (transferred) + if (transferred) { + assert(transfer->actual_length >= 0); *transferred = transfer->actual_length; + } switch (transfer->status) { case LIBUSB_TRANSFER_COMPLETED: @@ -312,9 +315,9 @@ int API_EXPORTED libusb_bulk_transfer(libusb_device_handle *dev_handle, * \param length for bulk writes, the number of bytes from data to be sent. for * bulk reads, the maximum number of bytes to receive into the data buffer. * \param transferred output location for the number of bytes actually - * transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105), - * it is legal to pass a NULL pointer if you do not wish to receive this - * information. + * transferred. Will never be negative. Since version 1.0.21 + * (\ref LIBUSB_API_VERSION >= 0x01000105), it is legal to pass a NULL + * pointer if you do not wish to receive this information. * \param timeout timeout (in milliseconds) that this function should wait * before giving up due to no response being received. For an unlimited * timeout, use value 0. diff --git a/libusb/version_nano.h b/libusb/version_nano.h index b22809b..a859d27 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h @@ -1 +1 @@ -#define LIBUSB_NANO 11883 +#define LIBUSB_NANO 11893 diff --git a/tests/macos.c b/tests/macos.c index a7b1231..5dc3ba3 100644 --- a/tests/macos.c +++ b/tests/macos.c @@ -71,8 +71,8 @@ extern uint32_t libusb_testonly_fake_running_version; -extern int libusb_testonly_using_running_interface_version; -extern int libusb_testonly_using_running_device_version; +extern uint32_t libusb_testonly_using_running_interface_version; +extern uint32_t libusb_testonly_using_running_device_version; extern bool libusb_testonly_clear_running_version_cache; static libusb_testlib_result test_macos_version_fallback(void) {