From aef70a5839012a6109ad0d3b9ad4aababfaa6558 Mon Sep 17 00:00:00 2001 From: sago35 Date: Sun, 7 Jun 2026 20:32:52 +0900 Subject: [PATCH] machine/usb: fix truncated USB string descriptor when host requests short maxLen (#5449) * machine/usb: fix truncated USB string descriptor when host requests short maxLen * fix binary size --- builder/sizes_test.go | 2 +- src/machine/usb.go | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/builder/sizes_test.go b/builder/sizes_test.go index 7d705ff78..469a00ed7 100644 --- a/builder/sizes_test.go +++ b/builder/sizes_test.go @@ -44,7 +44,7 @@ func TestBinarySize(t *testing.T) { // microcontrollers {"hifive1b", "examples/echo", 3817, 299, 0, 2252}, {"microbit", "examples/serial", 2820, 356, 8, 2248}, - {"wioterminal", "examples/pininterrupt", 7286, 1534, 120, 7248}, + {"wioterminal", "examples/pininterrupt", 7330, 1550, 120, 7248}, // TODO: also check wasm. Right now this is difficult, because // wasm binaries are run through wasm-opt and therefore the diff --git a/src/machine/usb.go b/src/machine/usb.go index 3833c7813..2b809a4e6 100644 --- a/src/machine/usb.go +++ b/src/machine/usb.go @@ -196,17 +196,18 @@ func sendDescriptorString(data string, maxLen uint16) { // Clamp the length. maxEncBytes := min(len(usb_trans_buffer), len(udd_ep_control_cache_buffer), int(maxLen)) - data = data[:min(len(data), (maxEncBytes-2)/2)] - // Write the header. - buf := usb_trans_buffer[:2*len(data)+2] + buf := usb_trans_buffer[:min(2*len(data)+2, maxEncBytes)] hdr, body := buf[:2], buf[2:] - hdr[0] = byte(len(buf)) + + // hdr[0] (bLength) should convey the "original total string length" before being limited by the host's maxLen. + hdr[0] = byte(2*len(data) + 2) hdr[1] = descriptor.TypeString // Convert the string to UTF16. // NOTE: Using range here would cause the length to disagree when multibyte codepoints are present. - for i := 0; i < len(data); i++ { + limit := min(len(data), len(body)/2) + for i := 0; i < limit; i++ { body[2*i] = byte(data[i]) body[2*i+1] = 0 }