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.