0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 9.0.1856: issues with formatting positional arguments

Problem:  issues with formatting positional arguments
Solution: fix them, add tests and documentation

closes: #12140
closes: #12985

Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Christ van Willegen <cvwillegen@gmail.com>
Tentatively fix message_test. Check NULL ptr.
This commit is contained in:
Christ van Willegen
2023-09-03 17:22:37 +02:00
committed by Christian Brabandt
parent 71ebf3baca
commit aa90d4f031
5 changed files with 59 additions and 35 deletions

View File

@@ -6707,8 +6707,13 @@ printf({fmt}, {expr1} ...) *printf()*
a conversion is wider than the field width, the field
is expanded to contain the conversion result.
The 'h' modifier indicates the argument is 16 bits.
The 'l' modifier indicates the argument is 32 bits.
The 'L' modifier indicates the argument is 64 bits.
The 'l' modifier indicates the argument is a long
integer. The size will be 32 bits or 64 bits
depending on your platform.
The "ll" modifier indicates the argument is 64 bits.
The b and B conversion specifiers never take a width
modifier and always assume their argument is a 64 bit
integer.
Generally, these modifiers are not useful. They are
ignored when type is known from the argument.

View File

@@ -3511,5 +3511,7 @@ EXTERN char e_member_str_type_mismatch_expected_str_but_got_str[]
INIT(= N_("E1406: Member \"%s\": type mismatch, expected %s but got %s"));
EXTERN char e_method_str_type_mismatch_expected_str_but_got_str[]
INIT(= N_("E1407: Member \"%s\": type mismatch, expected %s but got %s"));
EXTERN char e_aptypes_is_null_str_nr[]
INIT(= "E1408: Internal error: ap_types or ap_types[idx] is NULL: %d: %s");
// E1371 - E1399 unused

View File

@@ -40,6 +40,7 @@ char *fmt_012p = "%012p";
char *fmt_5S = "%5S";
char *fmt_06b = "%06b";
char *fmt_06pb = "%1$0.*2$b";
char *fmt_06pb2 = "%2$0*1$b";
char *fmt_212s = "%2$s %1$s %2$s";
char *fmt_21s = "%2$s %1$s";
@@ -442,6 +443,11 @@ test_vim_snprintf_positional(void)
assert(bsize == 0 || STRNCMP(buf, "deadbeef", bsize_int) == 0);
assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
n = vim_snprintf(buf, bsize, fmt_06pb2, 6, (uvarnumber_T)12);
assert(n == 6);
assert(bsize == 0 || STRNCMP(buf, "001100", bsize_int) == 0);
assert(bsize == 0 || buf[MIN(n, bsize_int)] == '\0');
n = vim_snprintf(buf, bsize, fmt_06pb, (uvarnumber_T)12, 6);
assert(n == 6);
assert(bsize == 0 || STRNCMP(buf, "001100", bsize_int) == 0);

View File

@@ -2251,8 +2251,7 @@ enum
*/
static int
format_typeof(
const char *type,
int usetvs UNUSED)
const char *type)
{
// allowed values: \0, h, l, L
char length_modifier = '\0';
@@ -2285,18 +2284,6 @@ format_typeof(
default: break;
}
# if defined(FEAT_EVAL)
if (usetvs)
{
switch (fmt_spec)
{
case 'd': case 'u': case 'o': case 'x': case 'X':
if (length_modifier == '\0')
length_modifier = 'L';
}
}
# endif
// get parameter value, do initial processing
switch (fmt_spec)
{
@@ -2330,7 +2317,7 @@ format_typeof(
if (fmt_spec == 'p')
return TYPE_POINTER;
else if (fmt_spec == 'b' || fmt_spec == 'B')
return TYPE_UNSIGNEDINT;
return TYPE_UNSIGNEDLONGLONGINT;
else if (fmt_spec == 'd')
{
// signed
@@ -2379,7 +2366,7 @@ format_typeof(
format_typename(
const char *type)
{
switch (format_typeof(type, FALSE))
switch (format_typeof(type))
{
case TYPE_INT:
return _(typename_int);
@@ -2467,7 +2454,7 @@ adjust_types(
}
else
{
if (format_typeof(type, FALSE) != format_typeof((*ap_types)[arg - 1], FALSE))
if (format_typeof(type) != format_typeof((*ap_types)[arg - 1]))
{
semsg(_( e_positional_arg_num_type_inconsistent_str_str), arg, format_typename(type), format_typename((*ap_types)[arg - 1]));
return FAIL;
@@ -2784,7 +2771,8 @@ skip_to_arg(
va_list ap_start,
va_list *ap,
int *arg_idx,
int *arg_cur)
int *arg_cur,
const char *fmt)
{
int arg_min = 0;
@@ -2809,9 +2797,17 @@ skip_to_arg(
for (*arg_cur = arg_min; *arg_cur < *arg_idx - 1; ++*arg_cur)
{
const char *p = ap_types[*arg_cur];
const char *p;
int fmt_type = format_typeof(p, TRUE);
if (ap_types == NULL || ap_types[*arg_cur] == NULL)
{
semsg(e_aptypes_is_null_str_nr, fmt, *arg_cur);
return;
}
p = ap_types[*arg_cur];
int fmt_type = format_typeof(p);
// get parameter value, do initial processing
switch (fmt_type)
@@ -3024,7 +3020,8 @@ vim_vsnprintf_typval(
# if defined(FEAT_EVAL)
tvs != NULL ? tv_nr(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, int));
if (j >= 0)
@@ -3084,7 +3081,8 @@ vim_vsnprintf_typval(
# if defined(FEAT_EVAL)
tvs != NULL ? tv_nr(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, int));
if (j >= 0)
@@ -3157,7 +3155,8 @@ vim_vsnprintf_typval(
# if defined(FEAT_EVAL)
tvs != NULL ? tv_nr(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, int));
// standard demands unsigned char
@@ -3172,7 +3171,8 @@ vim_vsnprintf_typval(
# if defined(FEAT_EVAL)
tvs != NULL ? tv_str(tvs, &arg_idx, &tofree) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, char *));
if (str_arg == NULL)
@@ -3269,7 +3269,8 @@ vim_vsnprintf_typval(
tvs != NULL ? (void *)tv_str(tvs, &arg_idx,
NULL) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, void *));
if (ptr_arg != NULL)
@@ -3282,7 +3283,8 @@ vim_vsnprintf_typval(
tvs != NULL ?
(uvarnumber_T)tv_nr(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, uvarnumber_T));
if (bin_arg != 0)
@@ -3300,7 +3302,8 @@ vim_vsnprintf_typval(
# if defined(FEAT_EVAL)
tvs != NULL ? tv_nr(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, int));
if (int_arg > 0)
@@ -3313,7 +3316,8 @@ vim_vsnprintf_typval(
# if defined(FEAT_EVAL)
tvs != NULL ? tv_nr(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, long int));
if (long_arg > 0)
@@ -3326,7 +3330,8 @@ vim_vsnprintf_typval(
# if defined(FEAT_EVAL)
tvs != NULL ? tv_nr(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, varnumber_T));
if (llong_arg > 0)
@@ -3348,7 +3353,8 @@ vim_vsnprintf_typval(
tvs != NULL ? (unsigned)
tv_nr(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, unsigned int));
if (uint_arg != 0)
@@ -3360,7 +3366,8 @@ vim_vsnprintf_typval(
tvs != NULL ? (unsigned long)
tv_nr(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, unsigned long int));
if (ulong_arg != 0)
@@ -3372,7 +3379,8 @@ vim_vsnprintf_typval(
tvs != NULL ? (uvarnumber_T)
tv_nr(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, uvarnumber_T));
if (ullong_arg != 0)
@@ -3574,7 +3582,8 @@ vim_vsnprintf_typval(
# if defined(FEAT_EVAL)
tvs != NULL ? tv_float(tvs, &arg_idx) :
# endif
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx, &arg_cur),
(skip_to_arg(ap_types, ap_start, &ap, &arg_idx,
&arg_cur, fmt),
va_arg(ap, double));
abs_f = f < 0 ? -f : f;

View File

@@ -699,6 +699,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1856,
/**/
1855,
/**/