* [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf
@ 2026-01-30 8:37 licheng.li
2026-01-30 8:37 ` [PATCH 2/2] selftests/nolibc: add tests for printf zero padding (0) licheng.li
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: licheng.li @ 2026-01-30 8:37 UTC (permalink / raw)
To: Willy Tarreau, David Laight
Cc: Thomas Weißschuh, linux-kernel, im.lechain
From: Cheng Li <im.lechain@gmail.com>
This patch correctly implements the '0' flag in __nolibc_printf() to
allow zero-padding for numeric and pointer outputs.
Thanks to David for pointing out the errors in the previous implementation.
The logic ensures that the sign ('-') for negative numbers or the prefix
('0x') for pointers is printed before the padding zeros, adhering to
standard printf behavior (e.g., producing "-0005" instead of "000-5").
Examples of the corrected padding logic:
- ("%05d", -5) -> "-0005"
- ("%05p", ptr) -> "0x00..."
Signed-off-by: Cheng Li <im.lechain@gmail.com>
---
tools/include/nolibc/stdio.h | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h
index f31b77f61d3b..8a4af259a31b 100644
--- a/tools/include/nolibc/stdio.h
+++ b/tools/include/nolibc/stdio.h
@@ -267,7 +267,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char
/* we're in an escape sequence, ofs == 1 */
escape = 0;
- if (c == '-') {
+ if (c == '-' || c == '0') {
padc = c;
c = fmt[ofs++];
}
@@ -364,9 +364,21 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char
if (n) {
w = len < n ? len : n;
n -= w;
+ if (padc == '0') {
+ if (outstr[0] == '-') {
+ if (cb(state, outstr, 1) != 0)
+ return -1;
+ outstr++;
+ }
+ if (outstr[0] == '0' && outstr[1] == 'x') {
+ if (cb(state, outstr, 2) != 0)
+ return -1;
+ outstr += 2;
+ }
+ }
while (width > w && padc != '-') {
written += 1;
- if (cb(state, " ", 1) != 0)
+ if (cb(state, &padc, 1) != 0)
return -1;
width--;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* [PATCH 2/2] selftests/nolibc: add tests for printf zero padding (0) 2026-01-30 8:37 [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf licheng.li @ 2026-01-30 8:37 ` licheng.li 2026-01-30 10:02 ` [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf David Laight 2026-01-31 10:18 ` Thomas Weißschuh 2 siblings, 0 replies; 10+ messages in thread From: licheng.li @ 2026-01-30 8:37 UTC (permalink / raw) To: Willy Tarreau, David Laight Cc: Thomas Weißschuh, linux-kernel, im.lechain From: Cheng Li <im.lechain@gmail.com> This patch adds validation for the '0' flag in printf() to ensure correct behavior for pointers, positive integers, and negative integers. The tests specifically verify that: - Pointers include the '0x' prefix before padding. - Negative numbers include the '-' sign before padding. - Width and padding are correctly calculated. Signed-off-by: Cheng Li <im.lechain@gmail.com> --- tools/testing/selftests/nolibc/nolibc-test.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index c11fcf6c5075..77bb8796aa3d 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -1723,6 +1723,9 @@ static int run_printf(int min, int max) CASE_TEST(truncation); EXPECT_VFPRINTF(25, "01234567890123456789", "%s", "0123456789012345678901234"); break; CASE_TEST(string_width); EXPECT_VFPRINTF(10, " 1", "%10s", "1"); break; CASE_TEST(number_width); EXPECT_VFPRINTF(10, " 1", "%10d", 1); break; + CASE_TEST(zero_pad_ptr); EXPECT_VFPRINTF(5, "0x005", "%05p", (void *)5); break; + CASE_TEST(zero_pad_int); EXPECT_VFPRINTF(5, "00005", "%05d", 5); break; + CASE_TEST(zero_pad_neg); EXPECT_VFPRINTF(5, "-0005", "%05d", -5); break; CASE_TEST(number_left); EXPECT_VFPRINTF(10, "|-5 |", "|%-8d|", -5); break; CASE_TEST(string_align); EXPECT_VFPRINTF(10, "|foo |", "|%-8s|", "foo"); break; CASE_TEST(width_trunc); EXPECT_VFPRINTF(25, " ", "%25d", 1); break; -- 2.52.0 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf 2026-01-30 8:37 [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf licheng.li 2026-01-30 8:37 ` [PATCH 2/2] selftests/nolibc: add tests for printf zero padding (0) licheng.li @ 2026-01-30 10:02 ` David Laight 2026-01-30 10:12 ` Cheng Li 2026-01-31 10:18 ` Thomas Weißschuh 2 siblings, 1 reply; 10+ messages in thread From: David Laight @ 2026-01-30 10:02 UTC (permalink / raw) To: licheng.li; +Cc: Willy Tarreau, Thomas Weißschuh, linux-kernel On Fri, 30 Jan 2026 16:37:35 +0800 "licheng.li" <im.lechain@gmail.com> wrote: > From: Cheng Li <im.lechain@gmail.com> > > This patch correctly implements the '0' flag in __nolibc_printf() to > allow zero-padding for numeric and pointer outputs. > > Thanks to David for pointing out the errors in the previous implementation. > > The logic ensures that the sign ('-') for negative numbers or the prefix > ('0x') for pointers is printed before the padding zeros, adhering to > standard printf behavior (e.g., producing "-0005" instead of "000-5"). I think it would be much better to change the contents of tmpbuf[] where it is filled with the converted number. You'd need to limit the number of zeros added (or the precision) to (say) 32 and then set 'outbuf = tmpbuf + 32' so that the zeros and sign/0x can be added at the front. There is the (annoying) subtle difference between %#05x and %#.5x just waiting to catch the unwary. David > > Examples of the corrected padding logic: > - ("%05d", -5) -> "-0005" > - ("%05p", ptr) -> "0x00..." > > Signed-off-by: Cheng Li <im.lechain@gmail.com> > --- > tools/include/nolibc/stdio.h | 16 ++++++++++++++-- > 1 file changed, 14 insertions(+), 2 deletions(-) > > diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h > index f31b77f61d3b..8a4af259a31b 100644 > --- a/tools/include/nolibc/stdio.h > +++ b/tools/include/nolibc/stdio.h > @@ -267,7 +267,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > /* we're in an escape sequence, ofs == 1 */ > escape = 0; > > - if (c == '-') { > + if (c == '-' || c == '0') { > padc = c; > c = fmt[ofs++]; > } > @@ -364,9 +364,21 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > if (n) { > w = len < n ? len : n; > n -= w; > + if (padc == '0') { > + if (outstr[0] == '-') { > + if (cb(state, outstr, 1) != 0) > + return -1; > + outstr++; > + } > + if (outstr[0] == '0' && outstr[1] == 'x') { > + if (cb(state, outstr, 2) != 0) > + return -1; > + outstr += 2; > + } > + } > while (width > w && padc != '-') { > written += 1; > - if (cb(state, " ", 1) != 0) > + if (cb(state, &padc, 1) != 0) > return -1; > width--; > } ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf 2026-01-30 10:02 ` [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf David Laight @ 2026-01-30 10:12 ` Cheng Li 2026-01-30 14:58 ` David Laight 0 siblings, 1 reply; 10+ messages in thread From: Cheng Li @ 2026-01-30 10:12 UTC (permalink / raw) To: David Laight; +Cc: Willy Tarreau, Thomas Weißschuh, linux-kernel David Laight <david.laight.linux@gmail.com> 于2026年1月30日周五 18:02写道: > > On Fri, 30 Jan 2026 16:37:35 +0800 > "licheng.li" <im.lechain@gmail.com> wrote: > > > From: Cheng Li <im.lechain@gmail.com> > > > > This patch correctly implements the '0' flag in __nolibc_printf() to > > allow zero-padding for numeric and pointer outputs. > > > > Thanks to David for pointing out the errors in the previous implementation. > > > > The logic ensures that the sign ('-') for negative numbers or the prefix > > ('0x') for pointers is printed before the padding zeros, adhering to > > standard printf behavior (e.g., producing "-0005" instead of "000-5"). > > I think it would be much better to change the contents of tmpbuf[] > where it is filled with the converted number. > You'd need to limit the number of zeros added (or the precision) to (say) 32 > and then set 'outbuf = tmpbuf + 32' so that the zeros and sign/0x can be > added at the front. Hi David, You are absolutely right. Modifying the buffer generation logic (tmpbuf) is indeed the robust way to handle sign/prefix insertion combined with padding/precision. My current approach of trying to handle it during the output phase is too fragile and misses edge cases (as I also realized regarding the negative sign issue). Given the complexity you mentioned (like the subtle differences in standard compliance) and your plan to implement full field precision, I will drop this "Zero Padding" patch entirely. It is better implemented as part of a proper precision support overhaul. I will focus on the "Left Alignment" patch. I am sending out v4 of that series later, which incorporates the code-swapping optimization you suggested earlier. Thanks for the detailed feedback. Best regards, Cheng > There is the (annoying) subtle difference between %#05x and %#.5x just > waiting to catch the unwary. > > David > > > > > Examples of the corrected padding logic: > > - ("%05d", -5) -> "-0005" > > - ("%05p", ptr) -> "0x00..." > > > > Signed-off-by: Cheng Li <im.lechain@gmail.com> > > --- > > tools/include/nolibc/stdio.h | 16 ++++++++++++++-- > > 1 file changed, 14 insertions(+), 2 deletions(-) > > > > diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h > > index f31b77f61d3b..8a4af259a31b 100644 > > --- a/tools/include/nolibc/stdio.h > > +++ b/tools/include/nolibc/stdio.h > > @@ -267,7 +267,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > > /* we're in an escape sequence, ofs == 1 */ > > escape = 0; > > > > - if (c == '-') { > > + if (c == '-' || c == '0') { > > padc = c; > > c = fmt[ofs++]; > > } > > @@ -364,9 +364,21 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > > if (n) { > > w = len < n ? len : n; > > n -= w; > > + if (padc == '0') { > > + if (outstr[0] == '-') { > > + if (cb(state, outstr, 1) != 0) > > + return -1; > > + outstr++; > > + } > > + if (outstr[0] == '0' && outstr[1] == 'x') { > > + if (cb(state, outstr, 2) != 0) > > + return -1; > > + outstr += 2; > > + } > > + } > > while (width > w && padc != '-') { > > written += 1; > > - if (cb(state, " ", 1) != 0) > > + if (cb(state, &padc, 1) != 0) > > return -1; > > width--; > > } > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf 2026-01-30 10:12 ` Cheng Li @ 2026-01-30 14:58 ` David Laight 2026-01-31 3:44 ` Cheng Li 0 siblings, 1 reply; 10+ messages in thread From: David Laight @ 2026-01-30 14:58 UTC (permalink / raw) To: Cheng Li; +Cc: Willy Tarreau, Thomas Weißschuh, linux-kernel On Fri, 30 Jan 2026 18:12:48 +0800 Cheng Li <im.lechain@gmail.com> wrote: > David Laight <david.laight.linux@gmail.com> 于2026年1月30日周五 18:02写道: > > > > On Fri, 30 Jan 2026 16:37:35 +0800 > > "licheng.li" <im.lechain@gmail.com> wrote: > > > > > From: Cheng Li <im.lechain@gmail.com> > > > > > > This patch correctly implements the '0' flag in __nolibc_printf() to > > > allow zero-padding for numeric and pointer outputs. > > > > > > Thanks to David for pointing out the errors in the previous implementation. > > > > > > The logic ensures that the sign ('-') for negative numbers or the prefix > > > ('0x') for pointers is printed before the padding zeros, adhering to > > > standard printf behavior (e.g., producing "-0005" instead of "000-5"). > > > > I think it would be much better to change the contents of tmpbuf[] > > where it is filled with the converted number. > > You'd need to limit the number of zeros added (or the precision) to (say) 32 > > and then set 'outbuf = tmpbuf + 32' so that the zeros and sign/0x can be > > added at the front. > > Hi David, > > You are absolutely right. Modifying the buffer generation logic > (tmpbuf) is indeed > the robust way to handle sign/prefix insertion combined with padding/precision. > My current approach of trying to handle it during the output phase is > too fragile > and misses edge cases (as I also realized regarding the negative sign issue). > > Given the complexity you mentioned (like the subtle differences in > standard compliance) > and your plan to implement full field precision, I will drop this > "Zero Padding" patch entirely. > It is better implemented as part of a proper precision support overhaul. > > I will focus on the "Left Alignment" patch. I am sending out v4 of > that series later, > which incorporates the code-swapping optimization you suggested earlier. > > Thanks for the detailed feedback. A good plan :-) I've written support for "%[#+- 0]*[.*][duxp]" but not tested the new bits yet. That is at +175 bytes after I used OPTIMZER_HIDE_VAR() to stop the compiler making a 'pigs breakfast' of the code (added nearly 100 bytes for a simple if() to avoid everything when the value and precision are both zero). David ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf 2026-01-30 14:58 ` David Laight @ 2026-01-31 3:44 ` Cheng Li 0 siblings, 0 replies; 10+ messages in thread From: Cheng Li @ 2026-01-31 3:44 UTC (permalink / raw) To: David Laight; +Cc: Willy Tarreau, Thomas Weißschuh, linux-kernel David Laight <david.laight.linux@gmail.com> 于2026年1月30日周五 22:58写道: > > On Fri, 30 Jan 2026 18:12:48 +0800 > Cheng Li <im.lechain@gmail.com> wrote: > > > David Laight <david.laight.linux@gmail.com> 于2026年1月30日周五 18:02写道: > > > > > > On Fri, 30 Jan 2026 16:37:35 +0800 > > > "licheng.li" <im.lechain@gmail.com> wrote: > > > > > > > From: Cheng Li <im.lechain@gmail.com> > > > > > > > > This patch correctly implements the '0' flag in __nolibc_printf() to > > > > allow zero-padding for numeric and pointer outputs. > > > > > > > > Thanks to David for pointing out the errors in the previous implementation. > > > > > > > > The logic ensures that the sign ('-') for negative numbers or the prefix > > > > ('0x') for pointers is printed before the padding zeros, adhering to > > > > standard printf behavior (e.g., producing "-0005" instead of "000-5"). > > > > > > I think it would be much better to change the contents of tmpbuf[] > > > where it is filled with the converted number. > > > You'd need to limit the number of zeros added (or the precision) to (say) 32 > > > and then set 'outbuf = tmpbuf + 32' so that the zeros and sign/0x can be > > > added at the front. > > > > Hi David, > > > > You are absolutely right. Modifying the buffer generation logic > > (tmpbuf) is indeed > > the robust way to handle sign/prefix insertion combined with padding/precision. > > My current approach of trying to handle it during the output phase is > > too fragile > > and misses edge cases (as I also realized regarding the negative sign issue). > > > > Given the complexity you mentioned (like the subtle differences in > > standard compliance) > > and your plan to implement full field precision, I will drop this > > "Zero Padding" patch entirely. > > It is better implemented as part of a proper precision support overhaul. > > > > I will focus on the "Left Alignment" patch. I am sending out v4 of > > that series later, > > which incorporates the code-swapping optimization you suggested earlier. > > > > Thanks for the detailed feedback. > > A good plan :-) > > I've written support for "%[#+- 0]*[.*][duxp]" but not tested the new bits yet. > > That is at +175 bytes after I used OPTIMZER_HIDE_VAR() to stop the compiler > making a 'pigs breakfast' of the code (added nearly 100 bytes for a simple if() > to avoid everything when the value and precision are both zero). Hi David, Glad to hear that! Implementing full spec support with such a small footprint (+175 bytes) sounds impressive. I look forward to seeing your patch series. Thanks again for the review and suggestions on the left-alignment patch. Best regards, Cheng > David ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf 2026-01-30 8:37 [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf licheng.li 2026-01-30 8:37 ` [PATCH 2/2] selftests/nolibc: add tests for printf zero padding (0) licheng.li 2026-01-30 10:02 ` [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf David Laight @ 2026-01-31 10:18 ` Thomas Weißschuh 2026-01-31 12:32 ` David Laight 2 siblings, 1 reply; 10+ messages in thread From: Thomas Weißschuh @ 2026-01-31 10:18 UTC (permalink / raw) To: licheng.li; +Cc: Willy Tarreau, David Laight, linux-kernel Hey Cheng, Jan 30, 2026 09:37:51 licheng.li <im.lechain@gmail.com>: > From: Cheng Li <im.lechain@gmail.com> > > This patch correctly implements the '0' flag in __nolibc_printf() to > allow zero-padding for numeric and pointer outputs. Thanks for (all of) your patches. I am not sure when exactly I can take a proper look at them. As we are currently fairly late in the 6.20/7.0 development cycle I would like move your patches into the next one. We can still discuss the patches and you can send new revisions and patches, but they won't be picked up until in a few weeks. > Thanks to David for pointing out the errors in the previous implementation. > > The logic ensures that the sign ('-') for negative numbers or the prefix > ('0x') for pointers is printed before the padding zeros, adhering to > standard printf behavior (e.g., producing "-0005" instead of "000-5"). > > Examples of the corrected padding logic: > - ("%05d", -5) -> "-0005" > - ("%05p", ptr) -> "0x00..." > > Signed-off-by: Cheng Li <im.lechain@gmail.com> > --- > tools/include/nolibc/stdio.h | 16 ++++++++++++++-- > 1 file changed, 14 insertions(+), 2 deletions(-) > > diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h > index f31b77f61d3b..8a4af259a31b 100644 > --- a/tools/include/nolibc/stdio.h > +++ b/tools/include/nolibc/stdio.h > @@ -267,7 +267,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > /* we're in an escape sequence, ofs == 1 */ > escape = 0; > > - if (c == '-') { > + if (c == '-' || c == '0') { > padc = c; > c = fmt[ofs++]; > } > @@ -364,9 +364,21 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > if (n) { > w = len < n ? len : n; > n -= w; > + if (padc == '0') { > + if (outstr[0] == '-') { > + if (cb(state, outstr, 1) != 0) > + return -1; > + outstr++; > + } > + if (outstr[0] == '0' && outstr[1] == 'x') { > + if (cb(state, outstr, 2) != 0) > + return -1; > + outstr += 2; > + } > + } > while (width > w && padc != '-') { > written += 1; > - if (cb(state, " ", 1) != 0) > + if (cb(state, &padc, 1) != 0) > return -1; > width--; > } > -- > 2.52.0 ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf 2026-01-31 10:18 ` Thomas Weißschuh @ 2026-01-31 12:32 ` David Laight 2026-02-01 0:49 ` Cheng Li 0 siblings, 1 reply; 10+ messages in thread From: David Laight @ 2026-01-31 12:32 UTC (permalink / raw) To: Thomas Weißschuh; +Cc: licheng.li, Willy Tarreau, linux-kernel On Sat, 31 Jan 2026 11:18:49 +0100 Thomas Weißschuh <linux@weissschuh.net> wrote: > Hey Cheng, > > Jan 30, 2026 09:37:51 licheng.li <im.lechain@gmail.com>: > > > From: Cheng Li <im.lechain@gmail.com> > > > > This patch correctly implements the '0' flag in __nolibc_printf() to > > allow zero-padding for numeric and pointer outputs. > > Thanks for (all of) your patches. > I am not sure when exactly I can take a proper look at them. > As we are currently fairly late in the 6.20/7.0 development cycle I would like move your patches into the next one. > We can still discuss the patches and you can send new revisions and patches, > but they won't be picked up until in a few weeks. Gives me time to re-write them :-) There is still a bug in the 'align left' code as well. snprintf(buf, 21, "%-25s", "abcd") outputs 20 spaces not "abcd" followed by 16. Easiest fix is to move the truncation in the cb() function. David > > > Thanks to David for pointing out the errors in the previous implementation. > > > > The logic ensures that the sign ('-') for negative numbers or the prefix > > ('0x') for pointers is printed before the padding zeros, adhering to > > standard printf behavior (e.g., producing "-0005" instead of "000-5"). > > > > Examples of the corrected padding logic: > > - ("%05d", -5) -> "-0005" > > - ("%05p", ptr) -> "0x00..." > > > > Signed-off-by: Cheng Li <im.lechain@gmail.com> > > --- > > tools/include/nolibc/stdio.h | 16 ++++++++++++++-- > > 1 file changed, 14 insertions(+), 2 deletions(-) > > > > diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h > > index f31b77f61d3b..8a4af259a31b 100644 > > --- a/tools/include/nolibc/stdio.h > > +++ b/tools/include/nolibc/stdio.h > > @@ -267,7 +267,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > > /* we're in an escape sequence, ofs == 1 */ > > escape = 0; > > > > - if (c == '-') { > > + if (c == '-' || c == '0') { > > padc = c; > > c = fmt[ofs++]; > > } > > @@ -364,9 +364,21 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > > if (n) { > > w = len < n ? len : n; > > n -= w; > > + if (padc == '0') { > > + if (outstr[0] == '-') { > > + if (cb(state, outstr, 1) != 0) > > + return -1; > > + outstr++; > > + } > > + if (outstr[0] == '0' && outstr[1] == 'x') { > > + if (cb(state, outstr, 2) != 0) > > + return -1; > > + outstr += 2; > > + } > > + } > > while (width > w && padc != '-') { > > written += 1; > > - if (cb(state, " ", 1) != 0) > > + if (cb(state, &padc, 1) != 0) > > return -1; > > width--; > > } > > -- > > 2.52.0 > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf 2026-01-31 12:32 ` David Laight @ 2026-02-01 0:49 ` Cheng Li 2026-02-01 8:56 ` David Laight 0 siblings, 1 reply; 10+ messages in thread From: Cheng Li @ 2026-02-01 0:49 UTC (permalink / raw) To: David Laight; +Cc: Thomas Weißschuh, Willy Tarreau, linux-kernel David Laight <david.laight.linux@gmail.com> 于2026年1月31日周六 20:32写道: > > On Sat, 31 Jan 2026 11:18:49 +0100 > Thomas Weißschuh <linux@weissschuh.net> wrote: > > > Hey Cheng, > > > > Jan 30, 2026 09:37:51 licheng.li <im.lechain@gmail.com>: > > > > > From: Cheng Li <im.lechain@gmail.com> > > > > > > This patch correctly implements the '0' flag in __nolibc_printf() to > > > allow zero-padding for numeric and pointer outputs. > > > > Thanks for (all of) your patches. > > I am not sure when exactly I can take a proper look at them. > > As we are currently fairly late in the 6.20/7.0 development cycle I would like move your patches into the next one. > > We can still discuss the patches and you can send new revisions and patches, > > but they won't be picked up until in a few weeks. > > Gives me time to re-write them :-) > > There is still a bug in the 'align left' code as well. > snprintf(buf, 21, "%-25s", "abcd") outputs 20 spaces not "abcd" followed by 16. > Easiest fix is to move the truncation in the cb() function. Hi David, I did a double-check on the `snprintf(buf, 21, "%-25s", "abcd")` case with the v4 patch. In my testing, the output content is actually correct ("abcd" followed by 16 spaces), and the return value is 25, which complies with the standard (representing the length if the buffer were infinite). **However**, you are right to be concerned about the logic. Upon closer inspection, I realized there is a potential **buffer overflow risk**. The current logic checks `len < n` for the string part, but the loop handling the padding does not rigorously check if the `width` exceeds the remaining buffer size `n`. If the buffer is full, the padding loop might continue trying to write via the callback, potentially causing an overflow if the callback relies on the caller to enforce limits. This confirms that your proposal to move the truncation logic entirely into the callback is the correct architectural fix. It would eliminate the complexity of manually managing `n` inside the parser and prevent such overflow issues by design. Therefore, I am perfectly happy to drop my current left-alignment patch entirely and wait for your refactor, as it provides a much safer architecture." Best regards, Cheng > David > > > > > > Thanks to David for pointing out the errors in the previous implementation. > > > > > > The logic ensures that the sign ('-') for negative numbers or the prefix > > > ('0x') for pointers is printed before the padding zeros, adhering to > > > standard printf behavior (e.g., producing "-0005" instead of "000-5"). > > > > > > Examples of the corrected padding logic: > > > - ("%05d", -5) -> "-0005" > > > - ("%05p", ptr) -> "0x00..." > > > > > > Signed-off-by: Cheng Li <im.lechain@gmail.com> > > > --- > > > tools/include/nolibc/stdio.h | 16 ++++++++++++++-- > > > 1 file changed, 14 insertions(+), 2 deletions(-) > > > > > > diff --git a/tools/include/nolibc/stdio.h b/tools/include/nolibc/stdio.h > > > index f31b77f61d3b..8a4af259a31b 100644 > > > --- a/tools/include/nolibc/stdio.h > > > +++ b/tools/include/nolibc/stdio.h > > > @@ -267,7 +267,7 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > > > /* we're in an escape sequence, ofs == 1 */ > > > escape = 0; > > > > > > - if (c == '-') { > > > + if (c == '-' || c == '0') { > > > padc = c; > > > c = fmt[ofs++]; > > > } > > > @@ -364,9 +364,21 @@ int __nolibc_printf(__nolibc_printf_cb cb, intptr_t state, size_t n, const char > > > if (n) { > > > w = len < n ? len : n; > > > n -= w; > > > + if (padc == '0') { > > > + if (outstr[0] == '-') { > > > + if (cb(state, outstr, 1) != 0) > > > + return -1; > > > + outstr++; > > > + } > > > + if (outstr[0] == '0' && outstr[1] == 'x') { > > > + if (cb(state, outstr, 2) != 0) > > > + return -1; > > > + outstr += 2; > > > + } > > > + } > > > while (width > w && padc != '-') { > > > written += 1; > > > - if (cb(state, " ", 1) != 0) > > > + if (cb(state, &padc, 1) != 0) > > > return -1; > > > width--; > > > } > > > -- > > > 2.52.0 > > > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf 2026-02-01 0:49 ` Cheng Li @ 2026-02-01 8:56 ` David Laight 0 siblings, 0 replies; 10+ messages in thread From: David Laight @ 2026-02-01 8:56 UTC (permalink / raw) To: Cheng Li; +Cc: Thomas Weißschuh, Willy Tarreau, linux-kernel On Sun, 1 Feb 2026 08:49:37 +0800 Cheng Li <im.lechain@gmail.com> wrote: > David Laight <david.laight.linux@gmail.com> 于2026年1月31日周六 20:32写道: > > > > On Sat, 31 Jan 2026 11:18:49 +0100 > > Thomas Weißschuh <linux@weissschuh.net> wrote: > > > > > Hey Cheng, > > > > > > Jan 30, 2026 09:37:51 licheng.li <im.lechain@gmail.com>: > > > > > > > From: Cheng Li <im.lechain@gmail.com> > > > > > > > > This patch correctly implements the '0' flag in __nolibc_printf() to > > > > allow zero-padding for numeric and pointer outputs. > > > > > > Thanks for (all of) your patches. > > > I am not sure when exactly I can take a proper look at them. > > > As we are currently fairly late in the 6.20/7.0 development cycle I would like move your patches into the next one. > > > We can still discuss the patches and you can send new revisions and patches, > > > but they won't be picked up until in a few weeks. > > > > Gives me time to re-write them :-) > > > > There is still a bug in the 'align left' code as well. > > snprintf(buf, 21, "%-25s", "abcd") outputs 20 spaces not "abcd" followed by 16. > > Easiest fix is to move the truncation in the cb() function. > > Hi David, > > I did a double-check on the `snprintf(buf, 21, "%-25s", "abcd")` case > with the v4 patch. > > In my testing, the output content is actually correct ("abcd" followed > by 16 spaces), > and the return value is 25, which complies with the standard > (representing the length > if the buffer were infinite). I was probably checking a slightly different version where the '-' just caused the truncated "abcd" be output before the pad. > > **However**, you are right to be concerned about the logic. Upon > closer inspection, > I realized there is a potential **buffer overflow risk**. > ... > > Therefore, I am perfectly happy to drop my current left-alignment > patch entirely and > wait for your refactor, as it provides a much safer architecture." I've got it 'mostly rewritten', I'll remove your patches for "%-2s" from the front before I submit them. I'll put that change in early. David ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2026-02-01 8:56 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-01-30 8:37 [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf licheng.li 2026-01-30 8:37 ` [PATCH 2/2] selftests/nolibc: add tests for printf zero padding (0) licheng.li 2026-01-30 10:02 ` [PATCH 1/2] tools/nolibc: add support zero pad (0) in printf David Laight 2026-01-30 10:12 ` Cheng Li 2026-01-30 14:58 ` David Laight 2026-01-31 3:44 ` Cheng Li 2026-01-31 10:18 ` Thomas Weißschuh 2026-01-31 12:32 ` David Laight 2026-02-01 0:49 ` Cheng Li 2026-02-01 8:56 ` David Laight
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.