Update overflow checks in pcre2test to allow for ULONG_MAX==UINT32_MAX.
This commit is contained in:
parent
b34dbecb75
commit
215e2185e4
|
@ -302,6 +302,7 @@ define special values to indicate zero-terminated strings and unset offsets in
|
||||||
the offset vector (ovector). */
|
the offset vector (ovector). */
|
||||||
|
|
||||||
#define PCRE2_SIZE size_t
|
#define PCRE2_SIZE size_t
|
||||||
|
#define PCRE2_SIZE_MAX SIZE_MAX
|
||||||
#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0)
|
#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0)
|
||||||
#define PCRE2_UNSET (~(PCRE2_SIZE)0)
|
#define PCRE2_UNSET (~(PCRE2_SIZE)0)
|
||||||
|
|
||||||
|
|
|
@ -302,6 +302,7 @@ define special values to indicate zero-terminated strings and unset offsets in
|
||||||
the offset vector (ovector). */
|
the offset vector (ovector). */
|
||||||
|
|
||||||
#define PCRE2_SIZE size_t
|
#define PCRE2_SIZE size_t
|
||||||
|
#define PCRE2_SIZE_MAX SIZE_MAX
|
||||||
#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0)
|
#define PCRE2_ZERO_TERMINATED (~(PCRE2_SIZE)0)
|
||||||
#define PCRE2_UNSET (~(PCRE2_SIZE)0)
|
#define PCRE2_UNSET (~(PCRE2_SIZE)0)
|
||||||
|
|
||||||
|
|
|
@ -239,6 +239,22 @@ of PRIV avoids name clashes. */
|
||||||
#include "pcre2_tables.c"
|
#include "pcre2_tables.c"
|
||||||
#include "pcre2_ucd.c"
|
#include "pcre2_ucd.c"
|
||||||
|
|
||||||
|
/* 32-bit integer values in the input are read by strtoul() or strtol(). The
|
||||||
|
check needed for overflow depends on whether long ints are in fact longer than
|
||||||
|
ints. They are defined not to be shorter. */
|
||||||
|
|
||||||
|
#if ULONG_MAX > UINT32_MAX
|
||||||
|
#define U32OVERFLOW(x) (x > UINT32_MAX)
|
||||||
|
#else
|
||||||
|
#define U32OVERFLOW(x) (x == UINT32_MAX)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LONG_MAX > INT32_MAX
|
||||||
|
#define S32OVERFLOW(x) (x > INT32_MAX || x < INT32_MIN)
|
||||||
|
#else
|
||||||
|
#define S32OVERFLOW(x) (x == INT32_MAX || x == INT32_MIN)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* When PCRE2_CODE_UNIT_WIDTH is zero, pcre2_internal.h does not include
|
/* When PCRE2_CODE_UNIT_WIDTH is zero, pcre2_internal.h does not include
|
||||||
pcre2_intmodedep.h, which is where mode-dependent macros and structures are
|
pcre2_intmodedep.h, which is where mode-dependent macros and structures are
|
||||||
defined. We can now include it for each supported code unit width. Because
|
defined. We can now include it for each supported code unit width. Because
|
||||||
|
@ -3290,18 +3306,33 @@ for (;;)
|
||||||
case MOD_IN2: /* One or two unsigned integers */
|
case MOD_IN2: /* One or two unsigned integers */
|
||||||
if (!isdigit(*pp)) goto INVALID_VALUE;
|
if (!isdigit(*pp)) goto INVALID_VALUE;
|
||||||
uli = strtoul((const char *)pp, &endptr, 10);
|
uli = strtoul((const char *)pp, &endptr, 10);
|
||||||
if (uli > UINT32_MAX) goto INVALID_VALUE;
|
if (U32OVERFLOW(uli)) goto INVALID_VALUE;
|
||||||
((uint32_t *)field)[0] = (uint32_t)uli;
|
((uint32_t *)field)[0] = (uint32_t)uli;
|
||||||
if (*endptr == ':')
|
if (*endptr == ':')
|
||||||
{
|
{
|
||||||
uli = strtoul((const char *)endptr+1, &endptr, 10);
|
uli = strtoul((const char *)endptr+1, &endptr, 10);
|
||||||
if (uli > UINT32_MAX) goto INVALID_VALUE;
|
if (U32OVERFLOW(uli)) goto INVALID_VALUE;
|
||||||
((uint32_t *)field)[1] = (uint32_t)uli;
|
((uint32_t *)field)[1] = (uint32_t)uli;
|
||||||
}
|
}
|
||||||
else ((uint32_t *)field)[1] = 0;
|
else ((uint32_t *)field)[1] = 0;
|
||||||
pp = (uint8_t *)endptr;
|
pp = (uint8_t *)endptr;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* PCRE2_SIZE_MAX is usually SIZE_MAX, which may be greater, equal to, or
|
||||||
|
less than ULONG_MAX. So first test for overflowing the long int, and then
|
||||||
|
test for overflowing PCRE2_SIZE_MAX if it is smaller than ULONG_MAX. */
|
||||||
|
|
||||||
|
case MOD_SIZ: /* PCRE2_SIZE value */
|
||||||
|
if (!isdigit(*pp)) goto INVALID_VALUE;
|
||||||
|
uli = strtoul((const char *)pp, &endptr, 10);
|
||||||
|
if (uli == ULONG_MAX) goto INVALID_VALUE;
|
||||||
|
#if ULONG_MAX > PCRE2_SIZE_MAX
|
||||||
|
if (uli > PCRE2_SIZE_MAX) goto INVALID_VALUE;
|
||||||
|
#endif
|
||||||
|
*((PCRE2_SIZE *)field) = (PCRE2_SIZE)uli;
|
||||||
|
pp = (uint8_t *)endptr;
|
||||||
|
break;
|
||||||
|
|
||||||
case MOD_IND: /* Unsigned integer with default */
|
case MOD_IND: /* Unsigned integer with default */
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
{
|
{
|
||||||
|
@ -3310,18 +3341,10 @@ for (;;)
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
|
|
||||||
case MOD_SIZ: /* PCRE2_SIZE value */
|
|
||||||
if (!isdigit(*pp)) goto INVALID_VALUE;
|
|
||||||
uli = strtoul((const char *)pp, &endptr, 10);
|
|
||||||
if (uli == ULONG_MAX) goto INVALID_VALUE;
|
|
||||||
*((PCRE2_SIZE *)field) = (PCRE2_SIZE)uli;
|
|
||||||
pp = (uint8_t *)endptr;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MOD_INT: /* Unsigned integer */
|
case MOD_INT: /* Unsigned integer */
|
||||||
if (!isdigit(*pp)) goto INVALID_VALUE;
|
if (!isdigit(*pp)) goto INVALID_VALUE;
|
||||||
uli = strtoul((const char *)pp, &endptr, 10);
|
uli = strtoul((const char *)pp, &endptr, 10);
|
||||||
if (uli > UINT32_MAX) goto INVALID_VALUE;
|
if (U32OVERFLOW(uli)) goto INVALID_VALUE;
|
||||||
*((uint32_t *)field) = (uint32_t)uli;
|
*((uint32_t *)field) = (uint32_t)uli;
|
||||||
pp = (uint8_t *)endptr;
|
pp = (uint8_t *)endptr;
|
||||||
break;
|
break;
|
||||||
|
@ -3329,7 +3352,7 @@ for (;;)
|
||||||
case MOD_INS: /* Signed integer */
|
case MOD_INS: /* Signed integer */
|
||||||
if (!isdigit(*pp) && *pp != '-') goto INVALID_VALUE;
|
if (!isdigit(*pp) && *pp != '-') goto INVALID_VALUE;
|
||||||
li = strtol((const char *)pp, &endptr, 10);
|
li = strtol((const char *)pp, &endptr, 10);
|
||||||
if (li > INT32_MAX || li < INT32_MIN) goto INVALID_VALUE;
|
if (S32OVERFLOW(li)) goto INVALID_VALUE;
|
||||||
*((int32_t *)field) = (int32_t)li;
|
*((int32_t *)field) = (int32_t)li;
|
||||||
pp = (uint8_t *)endptr;
|
pp = (uint8_t *)endptr;
|
||||||
break;
|
break;
|
||||||
|
@ -3360,7 +3383,7 @@ for (;;)
|
||||||
int ct = MAXCPYGET - 1;
|
int ct = MAXCPYGET - 1;
|
||||||
int32_t value;
|
int32_t value;
|
||||||
li = strtol((const char *)pp, &endptr, 10);
|
li = strtol((const char *)pp, &endptr, 10);
|
||||||
if (li > INT32_MAX || li < INT32_MIN) goto INVALID_VALUE;
|
if (S32OVERFLOW(li)) goto INVALID_VALUE;
|
||||||
value = (int32_t)li;
|
value = (int32_t)li;
|
||||||
field = (char *)field - m->offset + m->value; /* Adjust field ptr */
|
field = (char *)field - m->offset + m->value; /* Adjust field ptr */
|
||||||
if (value >= 0) /* Add new number */
|
if (value >= 0) /* Add new number */
|
||||||
|
@ -6944,7 +6967,7 @@ while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0)
|
||||||
#else
|
#else
|
||||||
int rc;
|
int rc;
|
||||||
struct rlimit rlim;
|
struct rlimit rlim;
|
||||||
if (uli > UINT32_MAX)
|
if (U32OVERFLOW(uli))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "+++ Argument for -S is too big\n");
|
fprintf(stderr, "+++ Argument for -S is too big\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -6996,7 +7019,7 @@ while (argc > 1 && argv[op][0] == '-' && argv[op][1] != 0)
|
||||||
showtotaltimes = arg[1] == 'T';
|
showtotaltimes = arg[1] == 'T';
|
||||||
if (argc > 2 && (uli = strtoul(argv[op+1], &endptr, 10), *endptr == 0))
|
if (argc > 2 && (uli = strtoul(argv[op+1], &endptr, 10), *endptr == 0))
|
||||||
{
|
{
|
||||||
if (uli > INT32_MAX)
|
if (U32OVERFLOW(uli))
|
||||||
{
|
{
|
||||||
fprintf(stderr, "+++ Argument for %s is too big\n", arg);
|
fprintf(stderr, "+++ Argument for %s is too big\n", arg);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
Loading…
Reference in New Issue