On Tue, Oct 21, 2025 at 05:17:58PM +0200, Daniel Kiper wrote:
> On Fri, Oct 17, 2025 at 05:01:32PM +0800, Michael Chang via Grub-devel wrote:
> > Add support for the 'z' length modifier in the printf code. This allows
> > printing of size_t and ssize_t values using %zu, %zd and related
> > formats. The parser maps 'z' to the correct integer width based on
> > sizeof (size_t).
> >
> > Signed-off-by: Michael Chang <[email protected]>
> > Reviewed-by: Neal Gompa <[email protected]>
> > Reviewed-by: Daniel Kiper <[email protected]>
> > ---
> >  grub-core/kern/misc.c | 20 ++++++++++++++++++++
> >  1 file changed, 20 insertions(+)
> >
> > diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
> > index 2b7922393..ff614add5 100644
> > --- a/grub-core/kern/misc.c
> > +++ b/grub-core/kern/misc.c
> > @@ -26,6 +26,7 @@
> >  #include <grub/i18n.h>
> >  #include <grub/types.h>
> >  #include <grub/charset.h>
> > +#include <stddef.h>
> >
> >  union printf_arg
> >  {
> > @@ -739,6 +740,9 @@ parse_printf_arg_fmt (const char *fmt0, struct 
> > printf_args *args,
> >    COMPILE_TIME_ASSERT (sizeof (long) <= sizeof (long long));
> >    COMPILE_TIME_ASSERT (sizeof (long long) == sizeof (void *)
> >                    || sizeof (int) == sizeof (void *));
> > +  COMPILE_TIME_ASSERT (sizeof (size_t) == sizeof (unsigned)
> > +                  || sizeof (size_t) == sizeof (unsigned long)
> > +                  || sizeof (size_t) == sizeof (unsigned long long));
> >
> >    fmt = fmt0;
> >    while ((c = *fmt++) != 0)
> > @@ -773,11 +777,17 @@ parse_printf_arg_fmt (const char *fmt0, struct 
> > printf_args *args,
> >     fmt++;
> >
> >        c = *fmt++;
> > +      if (c == 'z')
> > +   {
> > +     c = *fmt++;
> > +     goto do_count;
> > +   }
> >        if (c == 'l')
> >     c = *fmt++;
> >        if (c == 'l')
> >     c = *fmt++;
> >
> > + do_count:
> >        switch (c)
> >     {
> >     case 'p':
> > @@ -874,6 +884,14 @@ parse_printf_arg_fmt (const char *fmt0, struct 
> > printf_args *args,
> >       continue;
> >     }
> >
> > +      if (c == 'z')
> > +   {
> > +     c = *fmt++;
> > +     if (sizeof (size_t) == sizeof (unsigned long))
> > +       longfmt = 1;
> > +     else if (sizeof (size_t) == sizeof (unsigned long long))
> > +       longfmt = 2;
> 
> I have just realized we should probably have:
> 
> #ifdef GRUB_UTIL
>   if (sizeof (size_t) == sizeof (unsigned long))
>     longfmt = 1;
>   else if (sizeof (size_t) == sizeof (unsigned long long))
>     longfmt = 2;
> #else
>   if (sizeof (grub_size_t) == sizeof (unsigned long))
>     longfmt = 1;
>   else if (sizeof (grub_size_t) == sizeof (unsigned long long))
>     longfmt = 2;
> #endif
> 
> Same for COMPILE_TIME_ASSERT() above.
> 
> If it makes sense for you please post updated patch set. I want to merge
> it tomorrow...

The type size_t is not only used in Linux utilities but also by core
components that import sources from Linux libraries, such as libgcrypt
and zstd, which run in GRUB's arch-platform pre-boot environment.

Likewise, grub_size_t is not limited to the pre-boot context but is also
used in Linux utilities.

As a result, their scope is not restricted by conditional checks. Each
type should follow its own established convention for portable format
specifiers: 'z' for size_t and PRI[ux]GRUB_SIZE for grub_size_t. This
can avoid ambiguity.

Thanks,
Michael

> 
> Daniel

_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to