patch 9.1.1971: crash with invalid positional argument 0 in printf()

Commit: 
https://github.com/vim/vim/commit/98a0cbf05bd45fa6c4ede7b791fd21760bc587c8
Author: Christian Brabandt <[email protected]>
Date:   Thu Dec 11 20:51:03 2025 +0100

    patch 9.1.1971: crash with invalid positional argument 0 in printf()
    
    Problem:  crash with invalid positional argument 0 in printf()
    Solution: Reject positional arguments <= 0.
    
    closes: #18898
    
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt
index 3ac3d8a33..5b143cda8 100644
--- a/runtime/doc/builtin.txt
+++ b/runtime/doc/builtin.txt
@@ -1,4 +1,4 @@
-*builtin.txt*  For Vim version 9.1.  Last change: 2025 Dec 10
+*builtin.txt*  For Vim version 9.1.  Last change: 2025 Dec 11
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -8336,24 +8336,24 @@ printf({fmt}, {expr1} ...)                              
*printf()*
 
                                                        *E1502*
                You can re-use a [field-width] (or [precision]) argument: >
-                   echo printf("%1$d at width %2$d is: %01$*2$d", 1, 2)
+                   echo printf("%1$d at width %2$d is: %1$0*2$d", 1, 2)
 <                  1 at width 2 is: 01
 
                However, you can't use it as a different type: >
-                   echo printf("%1$d at width %2$ld is: %01$*2$d", 1, 2)
+                   echo printf("%1$d at width %2$ld is: %1$0*2$d", 1, 2)
 <                  E1502: Positional argument 2 used as field width reused as
                    different type: long int/int
 
                                                        *E1503*
                When a positional argument is used, but not the correct number
                or arguments is given, an error is raised: >
-                   echo printf("%1$d at width %2$d is: %01$*2$.*3$d", 1, 2)
+                   echo printf("%1$d at width %2$d is: %1$0*2$.*3$d", 1, 2)
 <                  E1503: Positional argument 3 out of bounds: %1$d at width
-                   %2$d is: %01$*2$.*3$d
+                   %2$d is: %1$0*2$.*3$d
 
                Only the first error is reported: >
-                   echo printf("%01$*2$.*3$d %4$d", 1, 2)
-<                  E1503: Positional argument 3 out of bounds: %01$*2$.*3$d
+                   echo printf("%1$0*2$.*3$d %4$d", 1, 2)
+<                  E1503: Positional argument 3 out of bounds: %1$0*2$.*3$d
                    %4$d
 
                                                        *E1504*
diff --git a/src/strings.c b/src/strings.c
index edf9057f0..8bcd38a8f 100644
--- a/src/strings.c
+++ b/src/strings.c
@@ -2843,6 +2843,12 @@ adjust_types(
     int *num_posarg,
     const char *type)
 {
+    if (arg <= 0)
+    {
+       semsg(_( e_invalid_format_specifier_str), type);
+       return FAIL;
+    }
+
     if (*ap_types == NULL || *num_posarg < arg)
     {
        int         idx;
@@ -2876,7 +2882,8 @@ adjust_types(
            {
                switch (pt[0])
                {
-                   case 'd': case 'i': break;
+                   case 'd':
+                   case 'i': break;
                    default:
                        semsg(_(e_positional_num_field_spec_reused_str_str), 
arg, format_typename((*ap_types)[arg - 1]), format_typename(type));
                        return FAIL;
diff --git a/src/testdir/test_format.vim b/src/testdir/test_format.vim
index b192938d4..b7c8b121a 100644
--- a/src/testdir/test_format.vim
+++ b/src/testdir/test_format.vim
@@ -299,6 +299,8 @@ func Test_printf_pos_errors()
   call v9.CheckLegacyAndVim9Failure(["call printf('%1$1$.5d', 5)"], "E1505:")
   call v9.CheckLegacyAndVim9Failure(["call printf('%1$5.1$d', 5)"], "E1505:")
   call v9.CheckLegacyAndVim9Failure(["call printf('%1$1$.1$d', 5)"], "E1505:")
+  call v9.CheckLegacyAndVim9Failure(["call printf('%1$*1$.*0$s')"], "E1505:")
+  call v9.CheckLegacyAndVim9Failure(["call printf('%*0$s')"], "E1505:")
 
   call v9.CheckLegacyAndVim9Failure(["call printf('%.123456789$d', 5)"], 
"E1510:")
   call v9.CheckLegacyAndVim9Failure(["call printf('%.123456789d', 5)"], 
"E1510:")

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1vTmpZ-00AFI9-Vt%40256bit.org.

Raspunde prin e-mail lui