public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox