fuzz_descriptor_parsers.c:clear_configuration:
  337|    501|{
  338|    501|	uint8_t i;
  339|       |
  340|    501|	if (config->interface) {
  ------------------
  |  Branch (340:6): [True: 501, False: 0]
  ------------------
  341|  3.01k|		for (i = 0; i < config->bNumInterfaces; i++)
  ------------------
  |  Branch (341:15): [True: 2.50k, False: 501]
  ------------------
  342|  2.50k|			clear_interface((struct libusb_interface *)
  343|  2.50k|					config->interface + i);
  344|    501|	}
  345|    501|	free((void *)config->interface);
  346|    501|	config->interface = NULL;
  347|    501|	config->bNumInterfaces = 0;
  348|    501|	free((void *)config->extra);
  349|       |	config->extra = NULL;
  350|    501|	config->extra_length = 0;
  351|    501|}
fuzz_descriptor_parsers.c:clear_interface:
  143|  2.70k|{
  144|  2.70k|	int i;
  145|       |
  146|  2.70k|	if (usb_interface->altsetting) {
  ------------------
  |  Branch (146:6): [True: 751, False: 1.95k]
  ------------------
  147|  4.73k|		for (i = 0; i < usb_interface->num_altsetting; i++) {
  ------------------
  |  Branch (147:15): [True: 3.98k, False: 751]
  ------------------
  148|  3.98k|			struct libusb_interface_descriptor *ifp =
  149|  3.98k|				(struct libusb_interface_descriptor *)
  150|  3.98k|				usb_interface->altsetting + i;
  151|       |
  152|  3.98k|			free((void *)ifp->extra);
  153|  3.98k|			ifp->extra = NULL;
  154|  3.98k|			ifp->extra_length = 0;
  155|  3.98k|			if (ifp->endpoint) {
  ------------------
  |  Branch (155:8): [True: 2.88k, False: 1.09k]
  ------------------
  156|  2.88k|				uint8_t j;
  157|       |
  158|  7.05k|				for (j = 0; j < ifp->bNumEndpoints; j++)
  ------------------
  |  Branch (158:17): [True: 4.17k, False: 2.88k]
  ------------------
  159|  4.17k|					clear_endpoint((struct libusb_endpoint_descriptor *)
  160|  4.17k|						       ifp->endpoint + j);
  161|  2.88k|			}
  162|  3.98k|			free((void *)ifp->endpoint);
  163|  3.98k|			ifp->endpoint = NULL;
  164|  3.98k|			ifp->bNumEndpoints = 0;
  165|  3.98k|		}
  166|    751|	}
  167|  2.70k|	free((void *)usb_interface->altsetting);
  168|       |	usb_interface->altsetting = NULL;
  169|  2.70k|	usb_interface->num_altsetting = 0;
  170|  2.70k|}
fuzz_descriptor_parsers.c:clear_endpoint:
   50|  4.17k|{
   51|  4.17k|	free((void *)endpoint->extra);
   52|  4.17k|}
fuzz_descriptor_parsers.c:ReadLittleEndian16:
   36|  2.85k|{
   37|  2.85k|	return (uint16_t)((uint16_t)p[1] << 8 |
   38|  2.85k|			  (uint16_t)p[0]);
   39|  2.85k|}
fuzz_descriptor_parsers.c:parse_configuration:
  355|    581|{
  356|    581|	uint8_t i;
  357|    581|	int r;
  358|    581|	const struct usbi_descriptor_header *header;
  359|    581|	struct libusb_interface *usb_interface;
  360|       |
  361|    581|	if (size < LIBUSB_DT_CONFIG_SIZE) {
  ------------------
  |  |  355|    581|#define LIBUSB_DT_CONFIG_SIZE			9
  ------------------
  |  Branch (361:6): [True: 0, False: 581]
  ------------------
  362|      0|		usbi_err(ctx, "short config descriptor read %d/%d",
  ------------------
  |  |  339|      0|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|      0|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  363|      0|			 size, LIBUSB_DT_CONFIG_SIZE);
  364|      0|		return LIBUSB_ERROR_IO;
  365|      0|	}
  366|       |
  367|    581|	uint8_t bLength = buffer[0];
  368|    581|	uint8_t bDescriptorType = buffer[1];
  369|    581|	uint16_t wTotalLength = ReadLittleEndian16(&buffer[2]);
  370|    581|	uint8_t bNumInterfaces = buffer[4];
  371|    581|	uint8_t bConfigurationValue = buffer[5];
  372|    581|	uint8_t iConfiguration = buffer[6];
  373|    581|	uint8_t bmAttributes = buffer[7];
  374|    581|	uint8_t MaxPower = buffer[8];
  375|       |
  376|    581|	if (bDescriptorType != LIBUSB_DT_CONFIG) {
  ------------------
  |  Branch (376:6): [True: 60, False: 521]
  ------------------
  377|     60|		usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
  ------------------
  |  |  339|     60|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     60|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  378|     60|			 bDescriptorType, LIBUSB_DT_CONFIG);
  379|     60|		return LIBUSB_ERROR_IO;
  380|    521|	} else if (bLength < LIBUSB_DT_CONFIG_SIZE) {
  ------------------
  |  |  355|    521|#define LIBUSB_DT_CONFIG_SIZE			9
  ------------------
  |  Branch (380:13): [True: 10, False: 511]
  ------------------
  381|     10|		usbi_err(ctx, "invalid config bLength (%u)", bLength);
  ------------------
  |  |  339|     10|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     10|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  382|     10|		return LIBUSB_ERROR_IO;
  383|    511|	} else if (bLength > size) {
  ------------------
  |  Branch (383:13): [True: 8, False: 503]
  ------------------
  384|      8|		usbi_err(ctx, "short config descriptor read %d/%u",
  ------------------
  |  |  339|      8|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|      8|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  385|      8|			 size, bLength);
  386|      8|		return LIBUSB_ERROR_IO;
  387|    503|	} else if (bNumInterfaces > USB_MAXINTERFACES) {
  ------------------
  |  |  159|    503|#define USB_MAXINTERFACES	32
  ------------------
  |  Branch (387:13): [True: 2, False: 501]
  ------------------
  388|      2|		usbi_err(ctx, "too many interfaces (%u)", bNumInterfaces);
  ------------------
  |  |  339|      2|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|      2|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  389|      2|		return LIBUSB_ERROR_IO;
  390|      2|	}
  391|       |
  392|    501|	usb_interface = (struct libusb_interface *)calloc(bNumInterfaces, sizeof(*usb_interface));
  393|    501|	if (!usb_interface)
  ------------------
  |  Branch (393:6): [True: 0, False: 501]
  ------------------
  394|      0|		return LIBUSB_ERROR_NO_MEM;
  395|       |
  396|    501|	buffer += bLength;
  397|    501|	size -= bLength;
  398|       |
  399|  1.06k|	for (i = 0; i < bNumInterfaces; i++) {
  ------------------
  |  Branch (399:14): [True: 972, False: 96]
  ------------------
  400|    972|		const uint8_t *begin;
  401|       |
  402|       |		/* Skip over the rest of the Class Specific or Vendor */
  403|       |		/*  Specific descriptors */
  404|    972|		begin = buffer;
  405|  1.83k|		while (size >= DESC_HEADER_LENGTH) {
  ------------------
  |  |   28|  1.83k|#define DESC_HEADER_LENGTH	2
  ------------------
  |  Branch (405:10): [True: 1.75k, False: 85]
  ------------------
  406|  1.75k|			header = (const struct usbi_descriptor_header *)buffer;
  407|  1.75k|			if (header->bLength < DESC_HEADER_LENGTH) {
  ------------------
  |  |   28|  1.75k|#define DESC_HEADER_LENGTH	2
  ------------------
  |  Branch (407:8): [True: 19, False: 1.73k]
  ------------------
  408|     19|				usbi_err(ctx,
  ------------------
  |  |  339|     19|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     19|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  409|     19|					 "invalid extra config desc len (%u)",
  410|     19|					 header->bLength);
  411|     19|				r = LIBUSB_ERROR_IO;
  412|     19|				goto err;
  413|  1.73k|			} else if (header->bLength > size) {
  ------------------
  |  Branch (413:15): [True: 54, False: 1.67k]
  ------------------
  414|     54|				usbi_warn(ctx,
  ------------------
  |  |  340|     54|#define usbi_warn(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     54|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  415|     54|					  "short extra config desc read %d/%u",
  416|     54|					  size, header->bLength);
  417|     54|				bNumInterfaces = i;
  418|     54|				goto finish;
  419|     54|			}
  420|       |
  421|       |			/* If we find another "proper" descriptor then we're done */
  422|  1.67k|			if (header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
  ------------------
  |  Branch (422:8): [True: 4, False: 1.67k]
  ------------------
  423|  1.67k|			    header->bDescriptorType == LIBUSB_DT_INTERFACE ||
  ------------------
  |  Branch (423:8): [True: 781, False: 892]
  ------------------
  424|    892|			    header->bDescriptorType == LIBUSB_DT_CONFIG ||
  ------------------
  |  Branch (424:8): [True: 15, False: 877]
  ------------------
  425|    877|			    header->bDescriptorType == LIBUSB_DT_DEVICE)
  ------------------
  |  Branch (425:8): [True: 14, False: 863]
  ------------------
  426|    814|				break;
  427|       |
  428|    863|			usbi_dbg(ctx, "skipping descriptor 0x%x", header->bDescriptorType);
  ------------------
  |  |  342|    863|#define usbi_dbg(ctx ,...)      	_usbi_log(ctx, LIBUSB_LOG_LEVEL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|    863|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  429|    863|			buffer += header->bLength;
  430|    863|			size -= header->bLength;
  431|    863|		}
  432|       |
  433|       |		/* Copy any unknown descriptors into a storage area for */
  434|       |		/*  drivers to later parse */
  435|    899|		ptrdiff_t len = buffer - begin;
  436|    899|		if (len > 0) {
  ------------------
  |  Branch (436:7): [True: 33, False: 866]
  ------------------
  437|     33|			size_t new_extra_len = (size_t)(config->extra_length) + (size_t)len;
  438|     33|			uint8_t *new_extra = (uint8_t *)realloc((void *)config->extra, new_extra_len);
  439|       |
  440|     33|			if (!new_extra) {
  ------------------
  |  Branch (440:8): [True: 0, False: 33]
  ------------------
  441|      0|				r = LIBUSB_ERROR_NO_MEM;
  442|      0|				goto err;
  443|      0|			}
  444|       |
  445|     33|			memcpy(new_extra + config->extra_length, begin, (size_t)len);
  446|     33|			config->extra = new_extra;
  447|     33|			config->extra_length = (int)new_extra_len;
  448|     33|		}
  449|       |
  450|    899|		r = parse_interface(ctx, usb_interface + i, buffer, size);
  451|    899|		if (r < 0)
  ------------------
  |  Branch (451:7): [True: 199, False: 700]
  ------------------
  452|    199|			goto err;
  453|    700|		if (r == 0) {
  ------------------
  |  Branch (453:7): [True: 133, False: 567]
  ------------------
  454|    133|			bNumInterfaces = i;
  455|    133|			break;
  456|    133|		}
  457|       |
  458|    567|		buffer += r;
  459|    567|		size -= r;
  460|    567|	}
  461|       |
  462|    283|finish:
  463|    283|	config->interface = usb_interface;
  464|    283|	config->bNumInterfaces = bNumInterfaces;
  465|    283|	config->bLength = bLength;
  466|    283|	config->bDescriptorType = bDescriptorType;
  467|    283|	config->wTotalLength = wTotalLength;
  468|    283|	config->bConfigurationValue = bConfigurationValue;
  469|    283|	config->iConfiguration = iConfiguration;
  470|    283|	config->bmAttributes = bmAttributes;
  471|    283|	config->MaxPower = MaxPower;
  472|       |
  473|    283|	return size;
  474|       |
  475|    218|err:
  476|       |	/* Even though we've failed, set these 2 fields so clear_configuration() can dealloc memory. */
  477|    218|	config->interface = usb_interface;
  478|    218|	config->bNumInterfaces = bNumInterfaces;
  479|       |
  480|    218|	clear_configuration(config);
  481|    218|	return r;
  482|    501|}
fuzz_descriptor_parsers.c:parse_interface:
  174|    899|{
  175|    899|	int r;
  176|    899|	int parsed = 0;
  177|    899|	int interface_number = -1;
  178|    899|	const struct usbi_descriptor_header *header;
  179|    899|	const struct usbi_interface_descriptor *if_desc;
  180|    899|	struct libusb_interface_descriptor *ifp;
  181|    899|	const uint8_t *begin;
  182|       |
  183|  4.13k|	while (size >= LIBUSB_DT_INTERFACE_SIZE) {
  ------------------
  |  |  356|  4.13k|#define LIBUSB_DT_INTERFACE_SIZE		9
  ------------------
  |  Branch (183:9): [True: 4.02k, False: 117]
  ------------------
  184|  4.02k|		uint8_t bLength = buffer[0];
  185|  4.02k|		uint8_t bDescriptorType = buffer[1];
  186|  4.02k|		uint8_t bInterfaceNumber = buffer[2];
  187|  4.02k|		uint8_t bAlternateSetting = buffer[3];
  188|  4.02k|		uint8_t bNumEndpoints = buffer[4];
  189|  4.02k|		uint8_t bInterfaceClass = buffer[5];
  190|  4.02k|		uint8_t bInterfaceSubClass = buffer[6];
  191|  4.02k|		uint8_t bInterfaceProtocol = buffer[7];
  192|  4.02k|		uint8_t iInterface = buffer[8];
  193|       |
  194|  4.02k|		if (bDescriptorType != LIBUSB_DT_INTERFACE) {
  ------------------
  |  Branch (194:7): [True: 16, False: 4.00k]
  ------------------
  195|     16|			usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
  ------------------
  |  |  339|     16|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     16|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  196|     16|				 bDescriptorType, LIBUSB_DT_INTERFACE);
  197|     16|			return parsed;
  198|  4.00k|		} else if (bLength < LIBUSB_DT_INTERFACE_SIZE) {
  ------------------
  |  |  356|  4.00k|#define LIBUSB_DT_INTERFACE_SIZE		9
  ------------------
  |  Branch (198:14): [True: 7, False: 3.99k]
  ------------------
  199|      7|			usbi_err(ctx, "invalid interface bLength (%u)",
  ------------------
  |  |  339|      7|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|      7|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  200|      7|				 bLength);
  201|      7|			r = LIBUSB_ERROR_IO;
  202|      7|			goto err;
  203|  3.99k|		} else if (bLength > size) {
  ------------------
  |  Branch (203:14): [True: 5, False: 3.99k]
  ------------------
  204|      5|			usbi_warn(ctx, "short intf descriptor read %d/%u",
  ------------------
  |  |  340|      5|#define usbi_warn(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|      5|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  205|      5|				 size, bLength);
  206|      5|			return parsed;
  207|  3.99k|		} else if (bNumEndpoints > USB_MAXENDPOINTS) {
  ------------------
  |  |  158|  3.99k|#define USB_MAXENDPOINTS	32
  ------------------
  |  Branch (207:14): [True: 11, False: 3.98k]
  ------------------
  208|     11|			usbi_err(ctx, "too many endpoints (%u)", bNumEndpoints);
  ------------------
  |  |  339|     11|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     11|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  209|     11|			r = LIBUSB_ERROR_IO;
  210|     11|			goto err;
  211|     11|		}
  212|       |
  213|  3.98k|		struct libusb_interface_descriptor *altsetting;
  214|  3.98k|		altsetting = (struct libusb_interface_descriptor *)realloc((void *)usb_interface->altsetting,
  215|  3.98k|			sizeof(*altsetting) * (size_t)(usb_interface->num_altsetting + 1));
  216|  3.98k|		if (!altsetting) {
  ------------------
  |  Branch (216:7): [True: 0, False: 3.98k]
  ------------------
  217|      0|			r = LIBUSB_ERROR_NO_MEM;
  218|      0|			goto err;
  219|      0|		}
  220|       |
  221|  3.98k|		ifp = altsetting + usb_interface->num_altsetting;
  222|  3.98k|		ifp->bLength = bLength;
  223|  3.98k|		ifp->bDescriptorType = bDescriptorType;
  224|  3.98k|		ifp->bInterfaceNumber = bInterfaceNumber;
  225|  3.98k|		ifp->bAlternateSetting = bAlternateSetting;
  226|  3.98k|		ifp->bNumEndpoints = bNumEndpoints;
  227|  3.98k|		ifp->bInterfaceClass = bInterfaceClass;
  228|  3.98k|		ifp->bInterfaceSubClass = bInterfaceSubClass;
  229|  3.98k|		ifp->bInterfaceProtocol = bInterfaceProtocol;
  230|  3.98k|		ifp->iInterface = iInterface;
  231|  3.98k|		ifp->extra = NULL;
  232|  3.98k|		ifp->extra_length = 0;
  233|  3.98k|		ifp->endpoint = NULL;
  234|       |
  235|  3.98k|		usb_interface->altsetting = altsetting;
  236|  3.98k|		usb_interface->num_altsetting++;
  237|       |
  238|  3.98k|		if (interface_number == -1)
  ------------------
  |  Branch (238:7): [True: 751, False: 3.23k]
  ------------------
  239|    751|			interface_number = ifp->bInterfaceNumber;
  240|       |
  241|       |		/* Skip over the interface */
  242|  3.98k|		buffer += ifp->bLength;
  243|  3.98k|		parsed += ifp->bLength;
  244|  3.98k|		size -= ifp->bLength;
  245|       |
  246|  3.98k|		begin = buffer;
  247|       |
  248|       |		/* Skip over any interface, class or vendor descriptors */
  249|  4.86k|		while (size >= DESC_HEADER_LENGTH) {
  ------------------
  |  |   28|  4.86k|#define DESC_HEADER_LENGTH	2
  ------------------
  |  Branch (249:10): [True: 4.75k, False: 113]
  ------------------
  250|  4.75k|			header = (const struct usbi_descriptor_header *)buffer;
  251|  4.75k|			if (header->bLength < DESC_HEADER_LENGTH) {
  ------------------
  |  |   28|  4.75k|#define DESC_HEADER_LENGTH	2
  ------------------
  |  Branch (251:8): [True: 24, False: 4.73k]
  ------------------
  252|     24|				usbi_err(ctx,
  ------------------
  |  |  339|     24|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     24|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  253|     24|					 "invalid extra intf desc len (%u)",
  254|     24|					 header->bLength);
  255|     24|				r = LIBUSB_ERROR_IO;
  256|     24|				goto err;
  257|  4.73k|			} else if (header->bLength > size) {
  ------------------
  |  Branch (257:15): [True: 18, False: 4.71k]
  ------------------
  258|     18|				usbi_warn(ctx,
  ------------------
  |  |  340|     18|#define usbi_warn(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     18|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  259|     18|					  "short extra intf desc read %d/%u",
  260|     18|					  size, header->bLength);
  261|       |				/* Keep the invariant: bNumEndpoints > 0 implies
  262|       |				 * endpoint != NULL. The endpoint array isn't
  263|       |				 * allocated yet on this early return. */
  264|     18|				ifp->bNumEndpoints = 0;
  265|     18|				return parsed;
  266|     18|			}
  267|       |
  268|       |			/* If we find another "proper" descriptor then we're done */
  269|  4.71k|			if (header->bDescriptorType == LIBUSB_DT_INTERFACE ||
  ------------------
  |  Branch (269:8): [True: 2.65k, False: 2.06k]
  ------------------
  270|  2.06k|			    header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
  ------------------
  |  Branch (270:8): [True: 1.15k, False: 904]
  ------------------
  271|    904|			    header->bDescriptorType == LIBUSB_DT_CONFIG ||
  ------------------
  |  Branch (271:8): [True: 6, False: 898]
  ------------------
  272|    898|			    header->bDescriptorType == LIBUSB_DT_DEVICE)
  ------------------
  |  Branch (272:8): [True: 11, False: 887]
  ------------------
  273|  3.82k|				break;
  274|       |
  275|    887|			buffer += header->bLength;
  276|    887|			parsed += header->bLength;
  277|    887|			size -= header->bLength;
  278|    887|		}
  279|       |
  280|       |		/* Copy any unknown descriptors into a storage area for */
  281|       |		/*  drivers to later parse */
  282|  3.94k|		ptrdiff_t len = buffer - begin;
  283|  3.94k|		if (len > 0) {
  ------------------
  |  Branch (283:7): [True: 313, False: 3.62k]
  ------------------
  284|    313|			void *extra = malloc((size_t)len);
  285|       |
  286|    313|			if (!extra) {
  ------------------
  |  Branch (286:8): [True: 0, False: 313]
  ------------------
  287|      0|				r = LIBUSB_ERROR_NO_MEM;
  288|      0|				goto err;
  289|      0|			}
  290|       |
  291|    313|			memcpy(extra, begin, (size_t)len);
  292|    313|			ifp->extra = (const unsigned char *)extra;
  293|    313|			ifp->extra_length = (int)len;
  294|    313|		}
  295|       |
  296|  3.94k|		if (ifp->bNumEndpoints > 0) {
  ------------------
  |  Branch (296:7): [True: 2.88k, False: 1.05k]
  ------------------
  297|  2.88k|			struct libusb_endpoint_descriptor *endpoint;
  298|  2.88k|			uint8_t i;
  299|       |
  300|  2.88k|			endpoint = (struct libusb_endpoint_descriptor *)calloc(ifp->bNumEndpoints, sizeof(*endpoint));
  301|  2.88k|			if (!endpoint) {
  ------------------
  |  Branch (301:8): [True: 0, False: 2.88k]
  ------------------
  302|      0|				r = LIBUSB_ERROR_NO_MEM;
  303|      0|				goto err;
  304|      0|			}
  305|       |
  306|  2.88k|			ifp->endpoint = endpoint;
  307|  5.14k|			for (i = 0; i < ifp->bNumEndpoints; i++) {
  ------------------
  |  Branch (307:16): [True: 4.21k, False: 930]
  ------------------
  308|  4.21k|				r = parse_endpoint(ctx, endpoint + i, buffer, size);
  309|  4.21k|				if (r < 0)
  ------------------
  |  Branch (309:9): [True: 157, False: 4.05k]
  ------------------
  310|    157|					goto err;
  311|  4.05k|				if (r == 0) {
  ------------------
  |  Branch (311:9): [True: 1.80k, False: 2.25k]
  ------------------
  312|  1.80k|					ifp->bNumEndpoints = i;
  313|  1.80k|					break;
  314|  1.80k|				}
  315|       |
  316|  2.25k|				buffer += r;
  317|  2.25k|				parsed += r;
  318|  2.25k|				size -= r;
  319|  2.25k|			}
  320|  2.88k|		}
  321|       |
  322|       |		/* We check to see if it's an alternate to this one */
  323|  3.78k|		if_desc = (const struct usbi_interface_descriptor *)buffer;
  324|  3.78k|		if (size < LIBUSB_DT_INTERFACE_SIZE ||
  ------------------
  |  |  356|  7.56k|#define LIBUSB_DT_INTERFACE_SIZE		9
  ------------------
  |  Branch (324:7): [True: 140, False: 3.64k]
  ------------------
  325|  3.64k|		    if_desc->bDescriptorType != LIBUSB_DT_INTERFACE ||
  ------------------
  |  Branch (325:7): [True: 34, False: 3.60k]
  ------------------
  326|  3.60k|		    if_desc->bInterfaceNumber != interface_number)
  ------------------
  |  Branch (326:7): [True: 370, False: 3.23k]
  ------------------
  327|    544|			return parsed;
  328|  3.78k|	}
  329|       |
  330|    117|	return parsed;
  331|    199|err:
  332|    199|	clear_interface(usb_interface);
  333|    199|	return r;
  334|    899|}
fuzz_descriptor_parsers.c:parse_endpoint:
   56|  4.21k|{
   57|  4.21k|	const struct usbi_descriptor_header *header;
   58|  4.21k|	const uint8_t *begin;
   59|  4.21k|	void *extra;
   60|  4.21k|	int parsed = 0;
   61|       |
   62|  4.21k|	if (size < DESC_HEADER_LENGTH) {
  ------------------
  |  |   28|  4.21k|#define DESC_HEADER_LENGTH	2
  ------------------
  |  Branch (62:6): [True: 117, False: 4.09k]
  ------------------
   63|    117|		usbi_err(ctx, "short endpoint descriptor read %d/%d",
  ------------------
  |  |  339|    117|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|    117|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
   64|    117|			 size, DESC_HEADER_LENGTH);
   65|    117|		return LIBUSB_ERROR_IO;
   66|    117|	}
   67|       |
   68|  4.09k|	header = (const struct usbi_descriptor_header *)buffer;
   69|  4.09k|	if (header->bDescriptorType != LIBUSB_DT_ENDPOINT) {
  ------------------
  |  Branch (69:6): [True: 1.79k, False: 2.30k]
  ------------------
   70|  1.79k|		usbi_err(ctx, "unexpected descriptor 0x%x (expected 0x%x)",
  ------------------
  |  |  339|  1.79k|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|  1.79k|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
   71|  1.79k|			header->bDescriptorType, LIBUSB_DT_ENDPOINT);
   72|  1.79k|		return parsed;
   73|  2.30k|	} else if (header->bLength < LIBUSB_DT_ENDPOINT_SIZE) {
  ------------------
  |  |  357|  2.30k|#define LIBUSB_DT_ENDPOINT_SIZE			7
  ------------------
  |  Branch (73:13): [True: 24, False: 2.27k]
  ------------------
   74|     24|		usbi_err(ctx, "invalid endpoint bLength (%u)", header->bLength);
  ------------------
  |  |  339|     24|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     24|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
   75|     24|		return LIBUSB_ERROR_IO;
   76|  2.27k|	} else if (header->bLength > size) {
  ------------------
  |  Branch (76:13): [True: 8, False: 2.27k]
  ------------------
   77|      8|		usbi_warn(ctx, "short endpoint descriptor read %d/%u",
  ------------------
  |  |  340|      8|#define usbi_warn(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|      8|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
   78|      8|			  size, header->bLength);
   79|      8|		return parsed;
   80|      8|	}
   81|       |
   82|  2.27k|	endpoint->bLength = buffer[0];
   83|  2.27k|	endpoint->bDescriptorType = buffer[1];
   84|  2.27k|	endpoint->bEndpointAddress = buffer[2];
   85|  2.27k|	endpoint->bmAttributes = buffer[3];
   86|  2.27k|	endpoint->wMaxPacketSize = ReadLittleEndian16(&buffer[4]);
   87|  2.27k|	endpoint->bInterval = buffer[6];
   88|  2.27k|	if (header->bLength >= LIBUSB_DT_ENDPOINT_AUDIO_SIZE) {
  ------------------
  |  |  358|  2.27k|#define LIBUSB_DT_ENDPOINT_AUDIO_SIZE		9	/* Audio extension */
  ------------------
  |  Branch (88:6): [True: 402, False: 1.86k]
  ------------------
   89|    402|		endpoint->bRefresh = buffer[7];
   90|    402|		endpoint->bSynchAddress = buffer[8];
   91|    402|	}
   92|       |
   93|  2.27k|	buffer += header->bLength;
   94|  2.27k|	size -= header->bLength;
   95|  2.27k|	parsed += header->bLength;
   96|       |
   97|       |	/* Skip over the rest of the Class Specific or Vendor Specific */
   98|       |	/*  descriptors */
   99|  2.27k|	begin = buffer;
  100|  4.16k|	while (size >= DESC_HEADER_LENGTH) {
  ------------------
  |  |   28|  4.16k|#define DESC_HEADER_LENGTH	2
  ------------------
  |  Branch (100:9): [True: 4.07k, False: 87]
  ------------------
  101|  4.07k|		header = (const struct usbi_descriptor_header *)buffer;
  102|  4.07k|		if (header->bLength < DESC_HEADER_LENGTH) {
  ------------------
  |  |   28|  4.07k|#define DESC_HEADER_LENGTH	2
  ------------------
  |  Branch (102:7): [True: 16, False: 4.06k]
  ------------------
  103|     16|			usbi_err(ctx, "invalid extra ep desc len (%u)",
  ------------------
  |  |  339|     16|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     16|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  104|     16|				 header->bLength);
  105|     16|			return LIBUSB_ERROR_IO;
  106|  4.06k|		} else if (header->bLength > size) {
  ------------------
  |  Branch (106:14): [True: 46, False: 4.01k]
  ------------------
  107|     46|			usbi_warn(ctx, "short extra ep desc read %d/%u",
  ------------------
  |  |  340|     46|#define usbi_warn(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|     46|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  108|     46|				  size, header->bLength);
  109|     46|			return parsed;
  110|     46|		}
  111|       |
  112|       |		/* If we find another "proper" descriptor then we're done  */
  113|  4.01k|		if (header->bDescriptorType == LIBUSB_DT_ENDPOINT ||
  ------------------
  |  Branch (113:7): [True: 1.14k, False: 2.87k]
  ------------------
  114|  2.87k|		    header->bDescriptorType == LIBUSB_DT_INTERFACE ||
  ------------------
  |  Branch (114:7): [True: 971, False: 1.90k]
  ------------------
  115|  1.90k|		    header->bDescriptorType == LIBUSB_DT_CONFIG ||
  ------------------
  |  Branch (115:7): [True: 3, False: 1.90k]
  ------------------
  116|  1.90k|		    header->bDescriptorType == LIBUSB_DT_DEVICE)
  ------------------
  |  Branch (116:7): [True: 5, False: 1.89k]
  ------------------
  117|  2.12k|			break;
  118|       |
  119|  1.89k|		usbi_dbg(ctx, "skipping descriptor 0x%x", header->bDescriptorType);
  ------------------
  |  |  342|  1.89k|#define usbi_dbg(ctx ,...)      	_usbi_log(ctx, LIBUSB_LOG_LEVEL_DEBUG, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|  1.89k|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
  120|  1.89k|		buffer += header->bLength;
  121|  1.89k|		size -= header->bLength;
  122|  1.89k|		parsed += header->bLength;
  123|  1.89k|	}
  124|       |
  125|       |	/* Copy any unknown descriptors into a storage area for drivers */
  126|       |	/*  to later parse */
  127|  2.20k|	ptrdiff_t len = buffer - begin;
  128|  2.20k|	if (len <= 0)
  ------------------
  |  Branch (128:6): [True: 1.73k, False: 476]
  ------------------
  129|  1.73k|		return parsed;
  130|       |
  131|    476|	extra = malloc((size_t)len);
  132|    476|	if (!extra)
  ------------------
  |  Branch (132:6): [True: 0, False: 476]
  ------------------
  133|      0|		return LIBUSB_ERROR_NO_MEM;
  134|       |
  135|    476|	memcpy(extra, begin, (size_t)len);
  136|    476|	endpoint->extra = (const unsigned char *)extra;
  137|    476|	endpoint->extra_length = (int)len;
  138|       |
  139|    476|	return parsed;
  140|    476|}
fuzz_descriptor_parsers.c:parse_iad_array:
 1394|    581|{
 1395|    581|	uint8_t i;
 1396|    581|	struct usbi_descriptor_header header;
 1397|    581|	int consumed = 0;
 1398|    581|	const uint8_t *buf = buffer;
 1399|    581|	struct libusb_interface_association_descriptor *iad;
 1400|    581|	int iad_length = 0;
 1401|       |
 1402|    581|	iad_array->iad = NULL;
 1403|    581|	iad_array->length = 0;
 1404|       |
 1405|    581|	if (size < LIBUSB_DT_CONFIG_SIZE) {
  ------------------
  |  |  355|    581|#define LIBUSB_DT_CONFIG_SIZE			9
  ------------------
  |  Branch (1405:6): [True: 0, False: 581]
  ------------------
 1406|      0|		usbi_err(ctx, "short config descriptor read %d/%d",
  ------------------
  |  |  339|      0|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|      0|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1407|      0|			 size, LIBUSB_DT_CONFIG_SIZE);
 1408|      0|		return LIBUSB_ERROR_IO;
 1409|      0|	}
 1410|       |
 1411|       |	/* First pass: Iterate through desc list, count number of IADs */
 1412|  28.7k|	while (size - consumed >= DESC_HEADER_LENGTH) {
  ------------------
  |  |   28|  28.7k|#define DESC_HEADER_LENGTH	2
  ------------------
  |  Branch (1412:9): [True: 28.3k, False: 364]
  ------------------
 1413|  28.3k|		header.bLength = buf[0];
 1414|  28.3k|		header.bDescriptorType = buf[1];
 1415|  28.3k|		if (header.bLength < DESC_HEADER_LENGTH) {
  ------------------
  |  |   28|  28.3k|#define DESC_HEADER_LENGTH	2
  ------------------
  |  Branch (1415:7): [True: 101, False: 28.2k]
  ------------------
 1416|    101|			usbi_err(ctx, "invalid descriptor bLength %d",
  ------------------
  |  |  339|    101|#define usbi_err(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_ERROR, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|    101|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1417|    101|				 header.bLength);
 1418|    101|			return LIBUSB_ERROR_IO;
 1419|    101|		}
 1420|  28.2k|		else if (header.bLength > size - consumed) {
  ------------------
  |  Branch (1420:12): [True: 116, False: 28.1k]
  ------------------
 1421|    116|			usbi_warn(ctx, "short config descriptor read %d/%u",
  ------------------
  |  |  340|    116|#define usbi_warn(ctx, ...)	_usbi_log(ctx, LIBUSB_LOG_LEVEL_WARNING, __VA_ARGS__)
  |  |  ------------------
  |  |  |  |  337|    116|#define _usbi_log(ctx, level, ...) usbi_log(ctx, level, __func__, __VA_ARGS__)
  |  |  ------------------
  ------------------
 1422|    116|					  size - consumed, header.bLength);
 1423|    116|			return LIBUSB_ERROR_IO;
 1424|    116|		}
 1425|  28.1k|		if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION)
  ------------------
  |  Branch (1425:7): [True: 17.5k, False: 10.6k]
  ------------------
 1426|  17.5k|			iad_length++;
 1427|  28.1k|		buf += header.bLength;
 1428|  28.1k|		consumed += header.bLength;
 1429|  28.1k|	}
 1430|       |
 1431|    364|	if (iad_length > 0) {
  ------------------
  |  Branch (1431:6): [True: 84, False: 280]
  ------------------
 1432|     84|		iad = (struct libusb_interface_association_descriptor *)calloc((size_t)iad_length, sizeof(*iad));
 1433|     84|		if (!iad)
  ------------------
  |  Branch (1433:7): [True: 0, False: 84]
  ------------------
 1434|      0|			return LIBUSB_ERROR_NO_MEM;
 1435|       |
 1436|     84|		iad_array->iad = iad;
 1437|     84|		iad_array->length = iad_length;
 1438|       |
 1439|       |		/* Second pass: Iterate through desc list, fill IAD structures */
 1440|     84|		i = 0;
 1441|  16.3k|		do {
 1442|  16.3k|			header.bLength = buffer[0];
 1443|  16.3k|			header.bDescriptorType = buffer[1];
 1444|  16.3k|			if (header.bDescriptorType == LIBUSB_DT_INTERFACE_ASSOCIATION && (size >= LIBUSB_DT_INTERFACE_ASSOCIATION_SIZE)) {
  ------------------
  |  |  363|  15.3k|#define LIBUSB_DT_INTERFACE_ASSOCIATION_SIZE	8
  ------------------
  |  Branch (1444:8): [True: 15.3k, False: 1.04k]
  |  Branch (1444:69): [True: 15.2k, False: 121]
  ------------------
 1445|  15.2k|				iad[i].bLength = buffer[0];
 1446|  15.2k|				iad[i].bDescriptorType = buffer[1];
 1447|  15.2k|				iad[i].bFirstInterface = buffer[2];
 1448|  15.2k|				iad[i].bInterfaceCount = buffer[3];
 1449|  15.2k|				iad[i].bFunctionClass = buffer[4];
 1450|  15.2k|				iad[i].bFunctionSubClass = buffer[5];
 1451|  15.2k|				iad[i].bFunctionProtocol = buffer[6];
 1452|  15.2k|				iad[i].iFunction = buffer[7];
 1453|  15.2k|				i++;
 1454|  15.2k|			}
 1455|       |
 1456|  16.3k|			if (size - header.bLength < DESC_HEADER_LENGTH) {
  ------------------
  |  |   28|  16.3k|#define DESC_HEADER_LENGTH	2
  ------------------
  |  Branch (1456:8): [True: 84, False: 16.3k]
  ------------------
 1457|     84|				break;
 1458|     84|			}
 1459|       |
 1460|  16.3k|			size -= header.bLength;
 1461|  16.3k|			buffer += header.bLength;
 1462|  16.3k|		} while (1);
  ------------------
  |  Branch (1462:12): [True: 16.3k, Folded]
  ------------------
 1463|     84|	}
 1464|       |
 1465|    364|	return LIBUSB_SUCCESS;
 1466|    364|}

usbi_log:
   35|  5.21k|              const char *function, const char *format, ...) {
   36|  5.21k|    (void)ctx; (void)level; (void)function; (void)format;
   37|  5.21k|}
LLVMFuzzerTestOneInput:
   53|    602|int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   54|       |    /* The limit of 8192 is comfortably above practical cases and
   55|       |     * still keeping libFuzzer iterations fast and the corpus small */
   56|    602|    if (size < LIBUSB_DT_CONFIG_SIZE || size > 8192)
  ------------------
  |  |  355|  1.20k|#define LIBUSB_DT_CONFIG_SIZE			9
  ------------------
  |  Branch (56:9): [True: 5, False: 597]
  |  Branch (56:41): [True: 16, False: 581]
  ------------------
   57|     21|        return 0;
   58|       |
   59|       |    /* Every call gets a fresh exact-size copy so any byte read past the
   60|       |     * end is caught by ASan. The fuzzer must not observe state between
   61|       |     * iterations. */
   62|    581|    uint8_t *buf;
   63|       |
   64|       |    /* (1) parse_configuration -> parse_interface -> parse_endpoint */
   65|    581|    buf = malloc(size);
   66|    581|    if (!buf) return 0;
  ------------------
  |  Branch (66:9): [True: 0, False: 581]
  ------------------
   67|    581|    memcpy(buf, data, size);
   68|    581|    {
   69|    581|        struct libusb_config_descriptor cfg;
   70|    581|        memset(&cfg, 0, sizeof(cfg));
   71|    581|        if (parse_configuration(NULL, &cfg, buf, (int)size) >= 0)
  ------------------
  |  Branch (71:13): [True: 283, False: 298]
  ------------------
   72|    283|            clear_configuration(&cfg);
   73|    581|    }
   74|    581|    free(buf);
   75|       |
   76|       |    /* (2) parse_iad_array */
   77|    581|    buf = malloc(size);
   78|    581|    if (!buf) return 0;
  ------------------
  |  Branch (78:9): [True: 0, False: 581]
  ------------------
   79|    581|    memcpy(buf, data, size);
   80|    581|    {
   81|    581|        struct libusb_interface_association_descriptor_array iad;
   82|    581|        memset(&iad, 0, sizeof(iad));
   83|    581|        if (parse_iad_array(NULL, &iad, buf, (int)size) == LIBUSB_SUCCESS)
  ------------------
  |  Branch (83:13): [True: 364, False: 217]
  ------------------
   84|    364|            free((void *)iad.iad);
   85|    581|    }
   86|    581|    free(buf);
   87|       |
   88|    581|    return 0;
   89|    581|}

