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:
committed by
Christian Brabandt
parent
71ebf3baca
commit
aa90d4f031
@@ -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.
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -699,6 +699,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1856,
|
||||
/**/
|
||||
1855,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user