From 6a8e27f7ee43169b9f6eb928b12e00d6306618ff Mon Sep 17 00:00:00 2001
From: Dean Camera <dean@fourwalledcubicle.com>
Date: Sat, 2 May 2009 13:05:25 +0000
Subject: [PATCH] Fixed Endpoint_Write_Control_* functions writing more data
 than expected by the host, causing it to panic (thanks to Johannes Raschke).

---
 Bootloaders/CDC/BootloaderCDC.c      |  2 +-
 Bootloaders/CDC/BootloaderCDC.h      |  2 +-
 Bootloaders/CDC/Descriptors.c        |  2 +-
 LUFA/Drivers/USB/LowLevel/Endpoint.c | 61 ++++++++++++++++------------
 4 files changed, 37 insertions(+), 30 deletions(-)

diff --git a/Bootloaders/CDC/BootloaderCDC.c b/Bootloaders/CDC/BootloaderCDC.c
index ef8707d34..f36c4fc3e 100644
--- a/Bootloaders/CDC/BootloaderCDC.c
+++ b/Bootloaders/CDC/BootloaderCDC.c
@@ -350,7 +350,7 @@ static void WriteNextResponseByte(const uint8_t Response)
 	/* Select the IN endpoint so that the next data byte can be written */
 	Endpoint_SelectEndpoint(CDC_TX_EPNUM);
 	
-	/* If OUT endpoint empty, clear it and wait for the next packet from the host */
+	/* If IN endpoint full, clear it and wait util ready for the next packet to the host */
 	if (!(Endpoint_IsReadWriteAllowed()))
 	{
 		Endpoint_ClearIN();
diff --git a/Bootloaders/CDC/BootloaderCDC.h b/Bootloaders/CDC/BootloaderCDC.h
index 7669b836c..e302a3966 100644
--- a/Bootloaders/CDC/BootloaderCDC.h
+++ b/Bootloaders/CDC/BootloaderCDC.h
@@ -82,7 +82,7 @@
 		#define BOOTLOADER_HWVERSION_MINOR   0x00
 
 		/** Eight character bootloader firmware identifier reported to the host when requested */
-		#define SOFTWARE_IDENTIFIER          "LUFA-CDC"
+		#define SOFTWARE_IDENTIFIER          "LUFACDC"
 
 	/* Event Handlers: */
 		/** Indicates that this module will catch the USB_Disconnect event when thrown by the library. */
diff --git a/Bootloaders/CDC/Descriptors.c b/Bootloaders/CDC/Descriptors.c
index e9787cf7f..06088d8f7 100644
--- a/Bootloaders/CDC/Descriptors.c
+++ b/Bootloaders/CDC/Descriptors.c
@@ -198,7 +198,7 @@ USB_Descriptor_String_t LanguageString =
  */
 USB_Descriptor_String_t ProductString =
 {
-	.Header                 = {.Size = USB_STRING_LEN(15), .Type = DTYPE_String},
+	.Header                 = {.Size = USB_STRING_LEN(18), .Type = DTYPE_String},
 		
 	.UnicodeString          = L"AVR CDC Bootloader"
 };
diff --git a/LUFA/Drivers/USB/LowLevel/Endpoint.c b/LUFA/Drivers/USB/LowLevel/Endpoint.c
index a872a00ff..f4f2bdc0b 100644
--- a/LUFA/Drivers/USB/LowLevel/Endpoint.c
+++ b/LUFA/Drivers/USB/LowLevel/Endpoint.c
@@ -288,9 +288,11 @@ uint8_t Endpoint_Read_Stream_BE(void* Buffer, uint16_t Length
 
 uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
 {
-	uint8_t* DataStream    = (uint8_t*)Buffer;
+	uint8_t* DataStream     = (uint8_t*)Buffer;
 	bool     LastPacketFull = false;
-	bool     ShortTransfer = (Length < USB_ControlRequest.wLength);
+	
+	if (Length > USB_ControlRequest.wLength)
+	  Length = USB_ControlRequest.wLength;
 	
 	while (Length && !(Endpoint_IsOUTReceived()))
 	{
@@ -309,7 +311,7 @@ uint8_t Endpoint_Write_Control_Stream_LE(const void* Buffer, uint16_t Length)
 	if (Endpoint_IsOUTReceived())
 	  return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
 	
-	if (LastPacketFull || ShortTransfer)
+	if (LastPacketFull)
 	{
 		while (!(Endpoint_IsINReady()));
 		Endpoint_ClearIN();
@@ -324,26 +326,29 @@ uint8_t Endpoint_Write_Control_Stream_BE(const void* Buffer, uint16_t Length)
 {
 	uint8_t* DataStream     = (uint8_t*)(Buffer + Length - 1);
 	bool     LastPacketFull = false;
-	bool     ShortTransfer  = (Length < USB_ControlRequest.wLength);
 	
+	if (Length > USB_ControlRequest.wLength)
+	  Length = USB_ControlRequest.wLength;
+
 	while (Length && !(Endpoint_IsOUTReceived()))
 	{
-		while (!(Endpoint_IsINReady()));
-		
-		while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
+		if (Endpoint_IsINReady())
 		{
-			Endpoint_Write_Byte(*(DataStream--));
-			Length--;
+			while (Length && (Endpoint_BytesInEndpoint() < USB_ControlEndpointSize))
+			{
+				Endpoint_Write_Byte(*(DataStream--));
+				Length--;
+			}
+			
+			LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
+			Endpoint_ClearIN();
 		}
-		
-		LastPacketFull = (Endpoint_BytesInEndpoint() == USB_ControlEndpointSize);
-		Endpoint_ClearIN();
 	}
 	
 	if (Endpoint_IsOUTReceived())
 	  return ENDPOINT_RWCSTREAM_ERROR_HostAborted;
 	
-	if (LastPacketFull || ShortTransfer)
+	if (LastPacketFull)
 	{
 		while (!(Endpoint_IsINReady()));
 		Endpoint_ClearIN();
@@ -360,15 +365,16 @@ uint8_t Endpoint_Read_Control_Stream_LE(void* Buffer, uint16_t Length)
 	
 	while (Length)
 	{
-		while (!(Endpoint_IsOUTReceived()));
-		
-		while (Length && Endpoint_BytesInEndpoint())
+		if (Endpoint_IsOUTReceived())
 		{
-			*(DataStream++) = Endpoint_Read_Byte();
-			Length--;
+			while (Length && Endpoint_BytesInEndpoint())
+			{
+				*(DataStream++) = Endpoint_Read_Byte();
+				Length--;
+			}
+			
+			Endpoint_ClearOUT();
 		}
-		
-		Endpoint_ClearOUT();
 	}
 	
 	while (!(Endpoint_IsINReady()));
@@ -382,15 +388,16 @@ uint8_t Endpoint_Read_Control_Stream_BE(void* Buffer, uint16_t Length)
 	
 	while (Length)
 	{
-		while (!(Endpoint_IsOUTReceived()));
-		
-		while (Length && Endpoint_BytesInEndpoint())
+		if (Endpoint_IsOUTReceived())
 		{
-			*(DataStream--) = Endpoint_Read_Byte();
-			Length--;
+			while (Length && Endpoint_BytesInEndpoint())
+			{
+				*(DataStream--) = Endpoint_Read_Byte();
+				Length--;
+			}
+			
+			Endpoint_ClearOUT();
 		}
-		
-		Endpoint_ClearOUT();
 	}
 	
 	while (!(Endpoint_IsINReady()));
-- 
GitLab