0
0
mirror of https://github.com/vim/vim.git synced 2025-09-04 21:33:48 -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* *Integer*
Number A 32 or 64 bit signed number. |expr-number| Number A 32 or 64 bit signed number. |expr-number|
64-bit Numbers are available only when compiled with the The number of bits is available in |v:numbersize|.
|+num64| feature.
Examples: -123 0x10 0177 0b1011 Examples: -123 0x10 0177 0b1011
Float A floating point number. |floating-point-format| *Float* 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 That is so that eval() can parse the string back to the same
value. Read-only. 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* *oldfiles-variable*
v:oldfiles List of file names that is loaded from the |viminfo| file on v:oldfiles List of file names that is loaded from the |viminfo| file on
startup. These are the files that Vim remembers marks for. 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 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* Mzscheme interface |mzscheme|
m *+mzscheme/dyn* Mzscheme interface |mzscheme-dynamic| |/dyn| m *+mzscheme/dyn* Mzscheme interface |mzscheme-dynamic| |/dyn|
m *+netbeans_intg* |netbeans| 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| m *+ole* Win32 GUI only: |ole-interface|
N *+packages* Loading |packages| N *+packages* Loading |packages|
N *+path_extra* Up/downwards search in 'path' and 'tags' 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: case VAR_NUMBER:
vim_snprintf((char *)buf, NUMBUFLEN, "%lld", vim_snprintf((char *)buf, NUMBUFLEN, "%lld",
(long_long_T)varp->vval.v_number); (varnumber_T)varp->vval.v_number);
return buf; return buf;
case VAR_FUNC: case VAR_FUNC:
case VAR_PARTIAL: case VAR_PARTIAL:

View File

@ -120,8 +120,9 @@ static struct vimvar
{VV_NAME("errors", VAR_LIST), 0}, {VV_NAME("errors", VAR_LIST), 0},
{VV_NAME("false", VAR_BOOL), VV_RO}, {VV_NAME("false", VAR_BOOL), VV_RO},
{VV_NAME("true", 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("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("vim_did_enter", VAR_NUMBER), VV_RO},
{VV_NAME("testing", VAR_NUMBER), 0}, {VV_NAME("testing", VAR_NUMBER), 0},
{VV_NAME("t_number", VAR_NUMBER), VV_RO}, {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_TRUE, VVAL_TRUE);
set_vim_var_nr(VV_NONE, VVAL_NONE); set_vim_var_nr(VV_NONE, VVAL_NONE);
set_vim_var_nr(VV_NULL, VVAL_NULL); 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_NUMBER, VAR_TYPE_NUMBER);
set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING); set_vim_var_nr(VV_TYPE_STRING, VAR_TYPE_STRING);

View File

@ -3016,14 +3016,14 @@ msg_add_lines(
*p++ = ' '; *p++ = ' ';
if (shortmess(SHM_LINES)) if (shortmess(SHM_LINES))
vim_snprintf((char *)p, IOSIZE - (p - IObuff), vim_snprintf((char *)p, IOSIZE - (p - IObuff),
"%ldL, %lldC", lnum, (long_long_T)nchars); "%ldL, %lldC", lnum, (varnumber_T)nchars);
else else
{ {
sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum); sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum);
p += STRLEN(p); p += STRLEN(p);
vim_snprintf((char *)p, IOSIZE - (p - IObuff), vim_snprintf((char *)p, IOSIZE - (p - IObuff),
NGETTEXT("%lld character", "%lld characters", nchars), 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: case VAR_NUMBER:
vim_snprintf((char *)numbuf, NUMBUFLEN, "%lld", vim_snprintf((char *)numbuf, NUMBUFLEN, "%lld",
(long_long_T)val->vval.v_number); (varnumber_T)val->vval.v_number);
ga_concat(gap, numbuf); ga_concat(gap, numbuf);
break; break;

View File

@ -4129,7 +4129,7 @@ infinity_str(int positive,
* Limited support for floating point was added: 'f', 'F', 'e', 'E', 'g', 'G'. * 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) * 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 * 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 '%'. * relevant for double-byte encodings where the second byte may be '%'.
@ -4371,7 +4371,7 @@ vim_vsnprintf_typval(
p++; p++;
if (length_modifier == 'l' && *p == 'l') if (length_modifier == 'l' && *p == 'l')
{ {
// double l = long long // double l = __int64 / varnumber_T
length_modifier = 'L'; length_modifier = 'L';
p++; p++;
} }
@ -4501,20 +4501,20 @@ vim_vsnprintf_typval(
// argument is never negative) // argument is never negative)
int arg_sign = 0; int arg_sign = 0;
// only defined for length modifier h, or for no // only set for length modifier h, or for no length
// length modifiers // modifiers
int int_arg = 0; int int_arg = 0;
unsigned int uint_arg = 0; unsigned int uint_arg = 0;
// only defined for length modifier l // only set for length modifier l
long int long_arg = 0; long int long_arg = 0;
unsigned long int ulong_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; varnumber_T llong_arg = 0;
uvarnumber_T ullong_arg = 0; uvarnumber_T ullong_arg = 0;
// only defined for b conversion // only set for b conversion
uvarnumber_T bin_arg = 0; uvarnumber_T bin_arg = 0;
// pointer argument value -only defined for p // pointer argument value -only defined for p

View File

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

View File

@ -1248,30 +1248,40 @@ typedef long_u hash_T; // Type for hi_hash
// Use 64-bit Number. // Use 64-bit Number.
#ifdef MSWIN #ifdef MSWIN
# ifdef PROTO # ifdef PROTO
typedef long varnumber_T; // workaround for cproto that doesn't recognize __int64
typedef unsigned long uvarnumber_T; typedef long varnumber_T;
# define VARNUM_MIN LONG_MIN typedef unsigned long uvarnumber_T;
# define VARNUM_MAX LONG_MAX # define VARNUM_MIN LONG_MIN
# define UVARNUM_MAX ULONG_MAX # define VARNUM_MAX LONG_MAX
# define UVARNUM_MAX ULONG_MAX
# else # else
typedef __int64 varnumber_T; typedef __int64 varnumber_T;
typedef unsigned __int64 uvarnumber_T; typedef unsigned __int64 uvarnumber_T;
# define VARNUM_MIN _I64_MIN # define VARNUM_MIN _I64_MIN
# define VARNUM_MAX _I64_MAX # define VARNUM_MAX _I64_MAX
# define UVARNUM_MAX _UI64_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 # 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 #else
typedef long varnumber_T; typedef long long varnumber_T;
typedef unsigned long uvarnumber_T; typedef unsigned long long uvarnumber_T;
# define VARNUM_MIN LONG_MIN # define VARNUM_MIN LLONG_MIN
# define VARNUM_MAX LONG_MAX # define VARNUM_MAX LLONG_MAX
# define UVARNUM_MAX ULONG_MAX # define UVARNUM_MAX ULLONG_MAX
#endif #endif
typedef double float_T; typedef double float_T;

View File

@ -228,3 +228,9 @@ func Test_excute_null()
call assert_fails('execute test_null_channel()', 'E908:') call assert_fails('execute test_null_channel()', 'E908:')
endif endif
endfunc 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[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
296,
/**/ /**/
295, 295,
/**/ /**/

View File

@ -328,16 +328,6 @@ typedef unsigned char char_u;
typedef unsigned short short_u; typedef unsigned short short_u;
typedef unsigned int int_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. // Make sure long_u is big enough to hold a pointer.
// On Win64, longs are 32 bits and pointers are 64 bits. // On Win64, longs are 32 bits and pointers are 64 bits.
// For printf() and scanf(), we need to take care of long_u specifically. // 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_ERRORS 67
#define VV_FALSE 68 #define VV_FALSE 68
#define VV_TRUE 69 #define VV_TRUE 69
#define VV_NULL 70 #define VV_NONE 70
#define VV_NONE 71 #define VV_NULL 71
#define VV_VIM_DID_ENTER 72 #define VV_NUMBERSIZE 72
#define VV_TESTING 73 #define VV_VIM_DID_ENTER 73
#define VV_TYPE_NUMBER 74 #define VV_TESTING 74
#define VV_TYPE_STRING 75 #define VV_TYPE_NUMBER 75
#define VV_TYPE_FUNC 76 #define VV_TYPE_STRING 76
#define VV_TYPE_LIST 77 #define VV_TYPE_FUNC 77
#define VV_TYPE_DICT 78 #define VV_TYPE_LIST 78
#define VV_TYPE_FLOAT 79 #define VV_TYPE_DICT 79
#define VV_TYPE_BOOL 80 #define VV_TYPE_FLOAT 80
#define VV_TYPE_NONE 81 #define VV_TYPE_BOOL 81
#define VV_TYPE_JOB 82 #define VV_TYPE_NONE 82
#define VV_TYPE_CHANNEL 83 #define VV_TYPE_JOB 83
#define VV_TYPE_BLOB 84 #define VV_TYPE_CHANNEL 84
#define VV_TERMRFGRESP 85 #define VV_TYPE_BLOB 85
#define VV_TERMRBGRESP 86 #define VV_TERMRFGRESP 86
#define VV_TERMU7RESP 87 #define VV_TERMRBGRESP 87
#define VV_TERMSTYLERESP 88 #define VV_TERMU7RESP 88
#define VV_TERMBLINKRESP 89 #define VV_TERMSTYLERESP 89
#define VV_EVENT 90 #define VV_TERMBLINKRESP 90
#define VV_VERSIONLONG 91 #define VV_EVENT 91
#define VV_ECHOSPACE 92 #define VV_VERSIONLONG 92
#define VV_ARGV 93 #define VV_ECHOSPACE 93
#define VV_LEN 94 // number of v: vars #define VV_ARGV 94
#define VV_LEN 95 // number of v: vars
// used for v_number in VAR_BOOL and VAR_SPECIAL // used for v_number in VAR_BOOL and VAR_SPECIAL
#define VVAL_FALSE 0L // VAR_BOOL #define VVAL_FALSE 0L // VAR_BOOL