]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
kern/misc: Add the "z" length modifier support
authorMichael Chang <mchang@suse.com>
Fri, 17 Oct 2025 09:01:32 +0000 (17:01 +0800)
committerDaniel Kiper <daniel.kiper@oracle.com>
Thu, 23 Oct 2025 17:15:00 +0000 (19:15 +0200)
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 <mchang@suse.com>
Reviewed-by: Neal Gompa <ngompa13@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
grub-core/kern/misc.c

index 2faff00ea6037241e7caa0eba270daa3ac729645..18c34b8eb1aab6c9f349492418a66f45c817b33a 100644 (file)
@@ -26,6 +26,7 @@
 #include <grub/i18n.h>
 #include <grub/types.h>
 #include <grub/charset.h>
+#include <stddef.h>
 
 union printf_arg
 {
@@ -832,6 +833,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)
@@ -866,11 +870,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':
@@ -967,6 +977,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;
+       }
       if (c == 'l')
        {
          c = *fmt++;
@@ -1143,6 +1161,8 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0,
        }
 
       c = *fmt++;
+      if (c == 'z')
+       c = *fmt++;
       if (c == 'l')
        c = *fmt++;
       if (c == 'l')