Skip to content

Commit a66fce6

Browse files
zeertzjqchrisbra
andcommitted
vim-patch:98a0cbf: patch 9.1.1971: crash with invalid positional argument 0 in printf() (#36919)
Problem: crash with invalid positional argument 0 in printf() Solution: Reject positional arguments <= 0. closes: vim/vim#18898 vim/vim@98a0cbf Co-authored-by: Christian Brabandt <cb@256bit.org>
1 parent cfb586a commit a66fce6

File tree

5 files changed

+25
-18
lines changed

5 files changed

+25
-18
lines changed

runtime/doc/vimfn.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7419,24 +7419,24 @@ printf({fmt}, {expr1} ...) *printf()*
74197419
<
74207420
*E1502*
74217421
You can re-use a [field-width] (or [precision]) argument: >vim
7422-
echo printf("%1$d at width %2$d is: %01$*2$d", 1, 2)
7422+
echo printf("%1$d at width %2$d is: %1$0*2$d", 1, 2)
74237423
" 1 at width 2 is: 01
74247424
<
74257425
However, you can't use it as a different type: >vim
7426-
echo printf("%1$d at width %2$ld is: %01$*2$d", 1, 2)
7426+
echo printf("%1$d at width %2$ld is: %1$0*2$d", 1, 2)
74277427
" E1502: Positional argument 2 used as field width reused as
74287428
" different type: long int/int
74297429
<
74307430
*E1503*
74317431
When a positional argument is used, but not the correct number
74327432
or arguments is given, an error is raised: >vim
7433-
echo printf("%1$d at width %2$d is: %01$*2$.*3$d", 1, 2)
7433+
echo printf("%1$d at width %2$d is: %1$0*2$.*3$d", 1, 2)
74347434
" E1503: Positional argument 3 out of bounds: %1$d at width
7435-
" %2$d is: %01$*2$.*3$d
7435+
" %2$d is: %1$0*2$.*3$d
74367436
<
74377437
Only the first error is reported: >vim
7438-
echo printf("%01$*2$.*3$d %4$d", 1, 2)
7439-
" E1503: Positional argument 3 out of bounds: %01$*2$.*3$d
7438+
echo printf("%1$0*2$.*3$d %4$d", 1, 2)
7439+
" E1503: Positional argument 3 out of bounds: %1$0*2$.*3$d
74407440
" %4$d
74417441
<
74427442
*E1504*

runtime/lua/vim/_meta/vimfn.lua

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/nvim/eval.lua

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8191,24 +8191,24 @@ M.funcs = {
81918191
<
81928192
*E1502*
81938193
You can re-use a [field-width] (or [precision]) argument: >vim
8194-
echo printf("%1$d at width %2$d is: %01$*2$d", 1, 2)
8194+
echo printf("%1$d at width %2$d is: %1$0*2$d", 1, 2)
81958195
" 1 at width 2 is: 01
81968196
<
81978197
However, you can't use it as a different type: >vim
8198-
echo printf("%1$d at width %2$ld is: %01$*2$d", 1, 2)
8198+
echo printf("%1$d at width %2$ld is: %1$0*2$d", 1, 2)
81998199
" E1502: Positional argument 2 used as field width reused as
82008200
" different type: long int/int
82018201
<
82028202
*E1503*
82038203
When a positional argument is used, but not the correct number
82048204
or arguments is given, an error is raised: >vim
8205-
echo printf("%1$d at width %2$d is: %01$*2$.*3$d", 1, 2)
8205+
echo printf("%1$d at width %2$d is: %1$0*2$.*3$d", 1, 2)
82068206
" E1503: Positional argument 3 out of bounds: %1$d at width
8207-
" %2$d is: %01$*2$.*3$d
8207+
" %2$d is: %1$0*2$.*3$d
82088208
<
82098209
Only the first error is reported: >vim
8210-
echo printf("%01$*2$.*3$d %4$d", 1, 2)
8211-
" E1503: Positional argument 3 out of bounds: %01$*2$.*3$d
8210+
echo printf("%1$0*2$.*3$d %4$d", 1, 2)
8211+
" E1503: Positional argument 3 out of bounds: %1$0*2$.*3$d
82128212
" %4$d
82138213
<
82148214
*E1504*

src/nvim/strings.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,6 +968,11 @@ static char *format_typename(const char *type)
968968
static int adjust_types(const char ***ap_types, int arg, int *num_posarg, const char *type)
969969
FUNC_ATTR_NONNULL_ALL
970970
{
971+
if (arg <= 0) {
972+
semsg(_(e_invalid_format_specifier_str), type);
973+
return FAIL;
974+
}
975+
971976
if (*ap_types == NULL || *num_posarg < arg) {
972977
const char **new_types = *ap_types == NULL
973978
? xcalloc((size_t)arg, sizeof(const char *))

test/old/testdir/test_format.vim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,8 @@ func Test_printf_pos_errors()
300300
call CheckLegacyAndVim9Failure(["call printf('%1$1$.5d', 5)"], "E1505:")
301301
call CheckLegacyAndVim9Failure(["call printf('%1$5.1$d', 5)"], "E1505:")
302302
call CheckLegacyAndVim9Failure(["call printf('%1$1$.1$d', 5)"], "E1505:")
303+
call CheckLegacyAndVim9Failure(["call printf('%1$*1$.*0$s')"], "E1505:")
304+
call CheckLegacyAndVim9Failure(["call printf('%*0$s')"], "E1505:")
303305

304306
call CheckLegacyAndVim9Failure(["call printf('%.123456789$d', 5)"], "E1510:")
305307
call CheckLegacyAndVim9Failure(["call printf('%.123456789d', 5)"], "E1510:")

0 commit comments

Comments
 (0)