diff --git a/libc/fmt/vcscanf.c b/libc/fmt/vcscanf.c index 4dda5b761..6098dc2a6 100644 --- a/libc/fmt/vcscanf.c +++ b/libc/fmt/vcscanf.c @@ -177,9 +177,11 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg, DecodeNumber: if (c != -1) { number = 0; + width = !width ? bits : width; do { diglet = kBase36[(unsigned char)c]; if (1 <= diglet && diglet <= base) { + width -= 1; number *= base; number += diglet - 1; } else if (thousands && diglet == ',') { @@ -187,7 +189,7 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg, } else { break; } - } while ((c = callback(arg)) != -1); + } while ((c = callback(arg)) != -1 && width > 0); if (!discard) { uint128_t bane = (uint128_t)1 << (bits - 1); if (!(number & ~((bane - 1) | (issigned ? 0 : bane))) || diff --git a/test/libc/fmt/sscanf_test.c b/test/libc/fmt/sscanf_test.c index 7705985d3..2ce8194fa 100644 --- a/test/libc/fmt/sscanf_test.c +++ b/test/libc/fmt/sscanf_test.c @@ -141,3 +141,11 @@ TEST(sscanf, testDiscard_notIncludedInCount) { ASSERT_EQ(1, sscanf("hello there", "%*s %8s", buf)); EXPECT_STREQ("there", buf); } + +TEST(sscanf, testFixedWidthFormat_Integer) { + int r, g, b; + ASSERT_EQ(3, sscanf("#321030", "#%2x%2b%2d", &r, &g, &b)); + ASSERT_EQ(0x32, r); + ASSERT_EQ(2, g); + ASSERT_EQ(30, b); +}