0
0
mirror of https://github.com/vim/vim.git synced 2025-08-31 20:53:42 -04:00

patch 8.2.0296: mixing up "long long" and __int64 may cause problems

Problem:    Mixing up "long long" and __int64 may cause problems. (John
            Marriott)
Solution:   Pass varnumber_T to vim_snprintf().  Add v:numbersize.
This commit is contained in:
Bram Moolenaar 2020-02-22 14:27:04 +01:00
parent c036e87bd7
commit f9706e9df0
12 changed files with 108 additions and 96 deletions

View File

@ -48,8 +48,7 @@ There are ten types of variables:
*Number* *Integer*
Number A 32 or 64 bit signed number. |expr-number|
64-bit Numbers are available only when compiled with the
|+num64| feature.
The number of bits is available in |v:numbersize|.
Examples: -123 0x10 0177 0b1011
Float A floating point number. |floating-point-format| *Float*
@ -1991,6 +1990,10 @@ v:null An empty String. Used to put "null" in JSON. See
That is so that eval() can parse the string back to the same
value. Read-only.
*v:numbersize* *numbersize-variable*
v:numbersize Number of bits in a Number. This is normally 64, but on some
systems it my be 32.
*v:oldfiles* *oldfiles-variable*
v:oldfiles List of file names that is loaded from the |viminfo| file on
startup. These are the files that Vim remembers marks for.

View File

@ -1,4 +1,4 @@
*various.txt* For Vim version 8.2. Last change: 2019 Dec 07
*various.txt* For Vim version 8.2. Last change: 2020 Feb 22
VIM REFERENCE MANUAL by Bram Moolenaar
@ -407,7 +407,9 @@ N *+multi_lang* non-English language support |multi-lang|
m *+mzscheme* Mzscheme interface |mzscheme|
m *+mzscheme/dyn* Mzscheme interface |mzscheme-dynamic| |/dyn|
m *+netbeans_intg* |netbeans|
*+num64* 64-bit Number support |Number|
*+num64* 64-bit Number support |Number|
Always enabled since 8.2.0271, use v:numbersize to
check the actual size of a Number.
m *+ole* Win32 GUI only: |ole-interface|
N *+packages* Loading |packages|
N *+path_extra* Up/downwards search in 'path' and 'tags'

View File

@ -5665,7 +5665,7 @@ tv_get_string_buf_chk(typval_T *varp, char_u *buf)
{
case VAR_NUMBER:
vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
(long_long_T)varp->vval.v_number);
(varnumber_T)varp->vval.v_number);
return buf;
case VAR_FUNC:
case VAR_PARTIAL:

View File

@ -120,8 +120,9 @@ static struct vimvar
{VV_NAME("errors", VAR_LIST), 0},
{VV_NAME("false", VAR_BOOL), VV_RO},
{VV_NAME("true", VAR_BOOL), VV_RO},
{VV_NAME("null", VAR_SPECIAL), VV_RO},
{VV_NAME("none", VAR_SPECIAL), VV_RO},
{VV_NAME("null", VAR_SPECIAL), VV_RO},
{VV_NAME("numbersize", VAR_NUMBER), VV_RO},
{VV_NAME("vim_did_enter", VAR_NUMBER), VV_RO},
{VV_NAME("testing", VAR_NUMBER), 0},
{VV_NAME("t_number", VAR_NUMBER), VV_RO},
@ -229,6 +230,7 @@ evalvars_init(void)
set_vim_var_nr(VV_TRUE, VVAL_TRUE);
set_vim_var_nr(VV_NONE, VVAL_NONE);
set_vim_var_nr(VV_NULL, VVAL_NULL);
set_vim_var_nr(VV_NUMBERSIZE, sizeof(varnumber_T) * 8);
set_vim_var_nr(VV_TYPE_NUMBER, VAR_TYPE_NUMBER);
set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING);

View File

@ -3016,14 +3016,14 @@ msg_add_lines(
*p++ = ' ';
if (shortmess(SHM_LINES))
vim_snprintf((char *)p, IOSIZE - (p - IObuff),
"%ldL, %lldC", lnum, (long_long_T)nchars);
"%ldL, %lldC", lnum, (varnumber_T)nchars);
else
{
sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum);
p += STRLEN(p);
vim_snprintf((char *)p, IOSIZE - (p - IObuff),
NGETTEXT("%lld character", "%lld characters", nchars),
(long_long_T)nchars);
(varnumber_T)nchars);
}
}

View File

@ -215,7 +215,7 @@ json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
case VAR_NUMBER:
vim_snprintf((char *)numbuf, NUMBUFLEN, "%lld",
(long_long_T)val->vval.v_number);
(varnumber_T)val->vval.v_number);
ga_concat(gap, numbuf);
break;

View File

@ -4129,7 +4129,7 @@ infinity_str(int positive,
* Limited support for floating point was added: 'f', 'F', 'e', 'E', 'g', 'G'.
*
* Length modifiers 'h' (short int) and 'l' (long int) and 'll' (long long int)
* are supported.
* are supported. NOTE: for 'll' the argument is varnumber_T or uvarnumber_T.
*
* The locale is not used, the string is used as a byte string. This is only
* relevant for double-byte encodings where the second byte may be '%'.
@ -4371,7 +4371,7 @@ vim_vsnprintf_typval(
p++;
if (length_modifier == 'l' && *p == 'l')
{
// double l = long long
// double l = __int64 / varnumber_T
length_modifier = 'L';
p++;
}
@ -4501,20 +4501,20 @@ vim_vsnprintf_typval(
// argument is never negative)
int arg_sign = 0;
// only defined for length modifier h, or for no
// length modifiers
// only set for length modifier h, or for no length
// modifiers
int int_arg = 0;
unsigned int uint_arg = 0;
// only defined for length modifier l
// only set for length modifier l
long int long_arg = 0;
unsigned long int ulong_arg = 0;
// only defined for length modifier ll
// only set for length modifier ll
varnumber_T llong_arg = 0;
uvarnumber_T ullong_arg = 0;
// only defined for b conversion
// only set for b conversion
uvarnumber_T bin_arg = 0;
// pointer argument value -only defined for p

View File

@ -3364,17 +3364,13 @@ do_addsub(
buf2[i] = '\0';
}
else if (pre == 0)
vim_snprintf((char *)buf2, NUMBUFLEN, "%llu",
(long_long_u_T)n);
vim_snprintf((char *)buf2, NUMBUFLEN, "%llu", (uvarnumber_T)n);
else if (pre == '0')
vim_snprintf((char *)buf2, NUMBUFLEN, "%llo",
(long_long_u_T)n);
vim_snprintf((char *)buf2, NUMBUFLEN, "%llo", (uvarnumber_T)n);
else if (pre && hexupper)
vim_snprintf((char *)buf2, NUMBUFLEN, "%llX",
(long_long_u_T)n);
vim_snprintf((char *)buf2, NUMBUFLEN, "%llX", (uvarnumber_T)n);
else
vim_snprintf((char *)buf2, NUMBUFLEN, "%llx",
(long_long_u_T)n);
vim_snprintf((char *)buf2, NUMBUFLEN, "%llx", (uvarnumber_T)n);
length -= (int)STRLEN(buf2);
/*
@ -3773,21 +3769,21 @@ cursor_pos_info(dict_T *dict)
_("Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Bytes"),
buf1, line_count_selected,
(long)curbuf->b_ml.ml_line_count,
(long_long_T)word_count_cursor,
(long_long_T)word_count,
(long_long_T)byte_count_cursor,
(long_long_T)byte_count);
(varnumber_T)word_count_cursor,
(varnumber_T)word_count,
(varnumber_T)byte_count_cursor,
(varnumber_T)byte_count);
else
vim_snprintf((char *)IObuff, IOSIZE,
_("Selected %s%ld of %ld Lines; %lld of %lld Words; %lld of %lld Chars; %lld of %lld Bytes"),
buf1, line_count_selected,
(long)curbuf->b_ml.ml_line_count,
(long_long_T)word_count_cursor,
(long_long_T)word_count,
(long_long_T)char_count_cursor,
(long_long_T)char_count,
(long_long_T)byte_count_cursor,
(long_long_T)byte_count);
(varnumber_T)word_count_cursor,
(varnumber_T)word_count,
(varnumber_T)char_count_cursor,
(varnumber_T)char_count,
(varnumber_T)byte_count_cursor,
(varnumber_T)byte_count);
}
else
{
@ -3805,17 +3801,17 @@ cursor_pos_info(dict_T *dict)
(char *)buf1, (char *)buf2,
(long)curwin->w_cursor.lnum,
(long)curbuf->b_ml.ml_line_count,
(long_long_T)word_count_cursor, (long_long_T)word_count,
(long_long_T)byte_count_cursor, (long_long_T)byte_count);
(varnumber_T)word_count_cursor, (varnumber_T)word_count,
(varnumber_T)byte_count_cursor, (varnumber_T)byte_count);
else
vim_snprintf((char *)IObuff, IOSIZE,
_("Col %s of %s; Line %ld of %ld; Word %lld of %lld; Char %lld of %lld; Byte %lld of %lld"),
(char *)buf1, (char *)buf2,
(long)curwin->w_cursor.lnum,
(long)curbuf->b_ml.ml_line_count,
(long_long_T)word_count_cursor, (long_long_T)word_count,
(long_long_T)char_count_cursor, (long_long_T)char_count,
(long_long_T)byte_count_cursor, (long_long_T)byte_count);
(varnumber_T)word_count_cursor, (varnumber_T)word_count,
(varnumber_T)char_count_cursor, (varnumber_T)char_count,
(varnumber_T)byte_count_cursor, (varnumber_T)byte_count);
}
}
@ -3825,7 +3821,7 @@ cursor_pos_info(dict_T *dict)
size_t len = STRLEN(IObuff);
vim_snprintf((char *)IObuff + len, IOSIZE - len,
_("(+%lld for BOM)"), (long_long_T)bom_count);
_("(+%lld for BOM)"), (varnumber_T)bom_count);
}
if (dict == NULL)
{

View File

@ -1248,30 +1248,40 @@ typedef long_u hash_T; // Type for hi_hash
// Use 64-bit Number.
#ifdef MSWIN
# ifdef PROTO
typedef long varnumber_T;
typedef unsigned long uvarnumber_T;
# define VARNUM_MIN LONG_MIN
# define VARNUM_MAX LONG_MAX
# define UVARNUM_MAX ULONG_MAX
// workaround for cproto that doesn't recognize __int64
typedef long varnumber_T;
typedef unsigned long uvarnumber_T;
# define VARNUM_MIN LONG_MIN
# define VARNUM_MAX LONG_MAX
# define UVARNUM_MAX ULONG_MAX
# else
typedef __int64 varnumber_T;
typedef unsigned __int64 uvarnumber_T;
# define VARNUM_MIN _I64_MIN
# define VARNUM_MAX _I64_MAX
# define UVARNUM_MAX _UI64_MAX
typedef __int64 varnumber_T;
typedef unsigned __int64 uvarnumber_T;
# define VARNUM_MIN _I64_MIN
# define VARNUM_MAX _I64_MAX
# define UVARNUM_MAX _UI64_MAX
# endif
#elif defined(HAVE_NO_LONG_LONG)
# if defined(HAVE_STDINT_H)
typedef int64_t varnumber_T;
typedef uint64_t uvarnumber_T;
# define VARNUM_MIN INT64_MIN
# define VARNUM_MAX INT64_MAX
# define UVARNUM_MAX UINT64_MAX
# else
// this may cause trouble for code that depends on 64 bit ints
typedef long varnumber_T;
typedef unsigned long uvarnumber_T;
# define VARNUM_MIN LONG_MIN
# define VARNUM_MAX LONG_MAX
# define UVARNUM_MAX ULONG_MAX
# endif
#elif defined(HAVE_STDINT_H)
typedef int64_t varnumber_T;
typedef uint64_t uvarnumber_T;
# define VARNUM_MIN INT64_MIN
# define VARNUM_MAX INT64_MAX
# define UVARNUM_MAX UINT64_MAX
#else
typedef long varnumber_T;
typedef unsigned long uvarnumber_T;
# define VARNUM_MIN LONG_MIN
# define VARNUM_MAX LONG_MAX
# define UVARNUM_MAX ULONG_MAX
typedef long long varnumber_T;
typedef unsigned long long uvarnumber_T;
# define VARNUM_MIN LLONG_MIN
# define VARNUM_MAX LLONG_MAX
# define UVARNUM_MAX ULLONG_MAX
#endif
typedef double float_T;

View File

@ -228,3 +228,9 @@ func Test_excute_null()
call assert_fails('execute test_null_channel()', 'E908:')
endif
endfunc
func Test_numbersize()
" This will fail on systems without 64 bit int support or when not configured
" correctly.
call assert_equal(64, v:numbersize)
endfunc

View File

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

View File

@ -328,16 +328,6 @@ typedef unsigned char char_u;
typedef unsigned short short_u;
typedef unsigned int int_u;
// Older systems do not have support for long long
// use a typedef instead of hard-coded long long
#ifdef HAVE_NO_LONG_LONG
typedef long long_long_T;
typedef long unsigned long_long_u_T;
#else
typedef long long long_long_T;
typedef long long unsigned long_long_u_T;
#endif
// Make sure long_u is big enough to hold a pointer.
// On Win64, longs are 32 bits and pointers are 64 bits.
// For printf() and scanf(), we need to take care of long_u specifically.
@ -1975,31 +1965,32 @@ typedef int sock_T;
#define VV_ERRORS 67
#define VV_FALSE 68
#define VV_TRUE 69
#define VV_NULL 70
#define VV_NONE 71
#define VV_VIM_DID_ENTER 72
#define VV_TESTING 73
#define VV_TYPE_NUMBER 74
#define VV_TYPE_STRING 75
#define VV_TYPE_FUNC 76
#define VV_TYPE_LIST 77
#define VV_TYPE_DICT 78
#define VV_TYPE_FLOAT 79
#define VV_TYPE_BOOL 80
#define VV_TYPE_NONE 81
#define VV_TYPE_JOB 82
#define VV_TYPE_CHANNEL 83
#define VV_TYPE_BLOB 84
#define VV_TERMRFGRESP 85
#define VV_TERMRBGRESP 86
#define VV_TERMU7RESP 87
#define VV_TERMSTYLERESP 88
#define VV_TERMBLINKRESP 89
#define VV_EVENT 90
#define VV_VERSIONLONG 91
#define VV_ECHOSPACE 92
#define VV_ARGV 93
#define VV_LEN 94 // number of v: vars
#define VV_NONE 70
#define VV_NULL 71
#define VV_NUMBERSIZE 72
#define VV_VIM_DID_ENTER 73
#define VV_TESTING 74
#define VV_TYPE_NUMBER 75
#define VV_TYPE_STRING 76
#define VV_TYPE_FUNC 77
#define VV_TYPE_LIST 78
#define VV_TYPE_DICT 79
#define VV_TYPE_FLOAT 80
#define VV_TYPE_BOOL 81
#define VV_TYPE_NONE 82
#define VV_TYPE_JOB 83
#define VV_TYPE_CHANNEL 84
#define VV_TYPE_BLOB 85
#define VV_TERMRFGRESP 86
#define VV_TERMRBGRESP 87
#define VV_TERMU7RESP 88
#define VV_TERMSTYLERESP 89
#define VV_TERMBLINKRESP 90
#define VV_EVENT 91
#define VV_VERSIONLONG 92
#define VV_ECHOSPACE 93
#define VV_ARGV 94
#define VV_LEN 95 // number of v: vars
// used for v_number in VAR_BOOL and VAR_SPECIAL
#define VVAL_FALSE 0L // VAR_BOOL