mirror of
https://github.com/neovim/neovim.git
synced 2025-10-07 10:26:31 +00:00
getdigits: introduce strict
, def
parameters
Problem: During a refactor long ago, we changed the `getdigits_*` familiy of functions to abort on overflow. But this is often wrong, because many of these codepaths are handling user input. Solution: Decide at each call-site whether to use "strict" mode. fix #5555
This commit is contained in:
@@ -166,7 +166,7 @@ int buf_init_chartab(buf_T *buf, int global)
|
||||
}
|
||||
|
||||
if (ascii_isdigit(*p)) {
|
||||
c = getdigits_int((char_u **)&p);
|
||||
c = getdigits_int((char_u **)&p, true, 0);
|
||||
} else {
|
||||
c = mb_ptr2char_adv(&p);
|
||||
}
|
||||
@@ -176,7 +176,7 @@ int buf_init_chartab(buf_T *buf, int global)
|
||||
++p;
|
||||
|
||||
if (ascii_isdigit(*p)) {
|
||||
c2 = getdigits_int((char_u **)&p);
|
||||
c2 = getdigits_int((char_u **)&p, true, 0);
|
||||
} else {
|
||||
c2 = mb_ptr2char_adv(&p);
|
||||
}
|
||||
@@ -1595,7 +1595,7 @@ char_u* skiptowhite_esc(char_u *p) {
|
||||
return p;
|
||||
}
|
||||
|
||||
/// Get a number from a string and skip over it, signalling overflows
|
||||
/// Gets a number from a string and skips over it, signalling overflow.
|
||||
///
|
||||
/// @param[out] pp A pointer to a pointer to char_u.
|
||||
/// It will be advanced past the read number.
|
||||
@@ -1606,48 +1606,58 @@ bool try_getdigits(char_u **pp, intmax_t *nr)
|
||||
{
|
||||
errno = 0;
|
||||
*nr = strtoimax((char *)(*pp), (char **)pp, 10);
|
||||
|
||||
if ((*nr == INTMAX_MIN || *nr == INTMAX_MAX)
|
||||
&& errno == ERANGE) {
|
||||
if (errno == ERANGE && (*nr == INTMAX_MIN || *nr == INTMAX_MAX)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Get a number from a string and skip over it.
|
||||
/// Gets a number from a string and skips over it.
|
||||
///
|
||||
/// @param[out] pp A pointer to a pointer to char_u.
|
||||
/// @param[out] pp Pointer to a pointer to char_u.
|
||||
/// It will be advanced past the read number.
|
||||
/// @param strict Abort on overflow.
|
||||
/// @param def Default value, if parsing fails or overflow occurs.
|
||||
///
|
||||
/// @return Number read from the string.
|
||||
intmax_t getdigits(char_u **pp)
|
||||
/// @return Number read from the string, or `def` on parse failure or overflow.
|
||||
intmax_t getdigits(char_u **pp, bool strict, intmax_t def)
|
||||
{
|
||||
intmax_t number;
|
||||
int ok = try_getdigits(pp, &number);
|
||||
|
||||
(void)ok; // Avoid "unused variable" warning in Release build
|
||||
assert(ok);
|
||||
|
||||
return number;
|
||||
if (strict && !ok) {
|
||||
abort();
|
||||
}
|
||||
return ok ? number : def;
|
||||
}
|
||||
|
||||
/// Get an int number from a string. Like getdigits(), but restricted to `int`.
|
||||
int getdigits_int(char_u **pp)
|
||||
/// Gets an int number from a string.
|
||||
///
|
||||
/// @see getdigits
|
||||
int getdigits_int(char_u **pp, bool strict, int def)
|
||||
{
|
||||
intmax_t number = getdigits(pp);
|
||||
intmax_t number = getdigits(pp, strict, def);
|
||||
#if SIZEOF_INTMAX_T > SIZEOF_INT
|
||||
assert(number >= INT_MIN && number <= INT_MAX);
|
||||
if (strict) {
|
||||
assert(number >= INT_MIN && number <= INT_MAX);
|
||||
} else if (!(number >= INT_MIN && number <= INT_MAX)) {
|
||||
return def;
|
||||
}
|
||||
#endif
|
||||
return (int)number;
|
||||
}
|
||||
|
||||
/// Get a long number from a string. Like getdigits(), but restricted to `long`.
|
||||
long getdigits_long(char_u **pp)
|
||||
/// Gets a long number from a string.
|
||||
///
|
||||
/// @see getdigits
|
||||
long getdigits_long(char_u **pp, bool strict, long def)
|
||||
{
|
||||
intmax_t number = getdigits(pp);
|
||||
intmax_t number = getdigits(pp, strict, def);
|
||||
#if SIZEOF_INTMAX_T > SIZEOF_LONG
|
||||
assert(number >= LONG_MIN && number <= LONG_MAX);
|
||||
if (strict) {
|
||||
assert(number >= LONG_MIN && number <= LONG_MAX);
|
||||
} else if (!(number >= LONG_MIN && number <= LONG_MAX)) {
|
||||
return def;
|
||||
}
|
||||
#endif
|
||||
return (long)number;
|
||||
}
|
||||
|
Reference in New Issue
Block a user