diff --git a/src/backend/utils/adt/numutils.c b/src/backend/utils/adt/numutils.c index 471fbb7ee6..12d8b7eb69 100644 --- a/src/backend/utils/adt/numutils.c +++ b/src/backend/utils/adt/numutils.c @@ -124,7 +124,7 @@ pg_strtoint16_safe(const char *s, Node *escontext) bool neg = false; /* skip leading spaces */ - while (likely(*ptr) && isspace((unsigned char) *ptr)) + while (isspace((unsigned char) *ptr)) ptr++; /* handle sign */ @@ -141,14 +141,17 @@ pg_strtoint16_safe(const char *s, Node *escontext) { firstdigit = ptr += 2; - while (*ptr) + while (1) { - if (isxdigit((unsigned char) *ptr)) + int8 digit = hexlookup[(unsigned char) *ptr]; + + if (likely(digit >= 0)) { if (unlikely(tmp > -(PG_INT16_MIN / 16))) goto out_of_range; - tmp = tmp * 16 + hexlookup[(unsigned char) *ptr++]; + tmp = tmp * 16 + digit; + ptr++; } else if (*ptr == '_') { @@ -165,14 +168,17 @@ pg_strtoint16_safe(const char *s, Node *escontext) { firstdigit = ptr += 2; - while (*ptr) + while (1) { - if (*ptr >= '0' && *ptr <= '7') + unsigned char digit = *ptr - '0'; + + if (likely(digit < 8)) { if (unlikely(tmp > -(PG_INT16_MIN / 8))) goto out_of_range; - tmp = tmp * 8 + (*ptr++ - '0'); + tmp = tmp * 8 + digit; + ptr++; } else if (*ptr == '_') { @@ -189,14 +195,17 @@ pg_strtoint16_safe(const char *s, Node *escontext) { firstdigit = ptr += 2; - while (*ptr) + while (1) { - if (*ptr >= '0' && *ptr <= '1') + unsigned char digit = *ptr - '0'; + + if (likely(digit < 2)) { if (unlikely(tmp > -(PG_INT16_MIN / 2))) goto out_of_range; - tmp = tmp * 2 + (*ptr++ - '0'); + tmp = tmp * 2 + digit; + ptr++; } else if (*ptr == '_') { @@ -213,14 +222,17 @@ pg_strtoint16_safe(const char *s, Node *escontext) { firstdigit = ptr; - while (*ptr) + while (1) { - if (isdigit((unsigned char) *ptr)) + unsigned char digit = *ptr - '0'; + + if (likely(digit < 10)) { if (unlikely(tmp > -(PG_INT16_MIN / 10))) goto out_of_range; - tmp = tmp * 10 + (*ptr++ - '0'); + tmp = tmp * 10 + digit; + ptr++; } else if (*ptr == '_') { @@ -302,7 +314,7 @@ pg_strtoint32_safe(const char *s, Node *escontext) bool neg = false; /* skip leading spaces */ - while (likely(*ptr) && isspace((unsigned char) *ptr)) + while (isspace((unsigned char) *ptr)) ptr++; /* handle sign */ @@ -319,14 +331,17 @@ pg_strtoint32_safe(const char *s, Node *escontext) { firstdigit = ptr += 2; - while (*ptr) + while (1) { - if (isxdigit((unsigned char) *ptr)) + int8 digit = hexlookup[(unsigned char) *ptr]; + + if (likely(digit >= 0)) { if (unlikely(tmp > -(PG_INT32_MIN / 16))) goto out_of_range; - tmp = tmp * 16 + hexlookup[(unsigned char) *ptr++]; + tmp = tmp * 16 + digit; + ptr++; } else if (*ptr == '_') { @@ -343,14 +358,17 @@ pg_strtoint32_safe(const char *s, Node *escontext) { firstdigit = ptr += 2; - while (*ptr) + while (1) { - if (*ptr >= '0' && *ptr <= '7') + unsigned char digit = *ptr - '0'; + + if (likely(digit < 8)) { if (unlikely(tmp > -(PG_INT32_MIN / 8))) goto out_of_range; - tmp = tmp * 8 + (*ptr++ - '0'); + tmp = tmp * 8 + digit; + ptr++; } else if (*ptr == '_') { @@ -367,14 +385,17 @@ pg_strtoint32_safe(const char *s, Node *escontext) { firstdigit = ptr += 2; - while (*ptr) + while (1) { - if (*ptr >= '0' && *ptr <= '1') + unsigned char digit = *ptr - '0'; + + if (likely(digit < 2)) { if (unlikely(tmp > -(PG_INT32_MIN / 2))) goto out_of_range; - tmp = tmp * 2 + (*ptr++ - '0'); + tmp = tmp * 2 + digit; + ptr++; } else if (*ptr == '_') { @@ -391,14 +412,17 @@ pg_strtoint32_safe(const char *s, Node *escontext) { firstdigit = ptr; - while (*ptr) + while (1) { - if (isdigit((unsigned char) *ptr)) + unsigned char digit = *ptr - '0'; + + if (likely(digit < 10)) { if (unlikely(tmp > -(PG_INT32_MIN / 10))) goto out_of_range; - tmp = tmp * 10 + (*ptr++ - '0'); + tmp = tmp * 10 + digit; + ptr++; } else if (*ptr == '_') { @@ -420,7 +444,7 @@ pg_strtoint32_safe(const char *s, Node *escontext) goto invalid_syntax; /* allow trailing whitespace, but not other trailing chars */ - while (*ptr != '\0' && isspace((unsigned char) *ptr)) + while (isspace((unsigned char) *ptr)) ptr++; if (unlikely(*ptr != '\0')) @@ -480,7 +504,7 @@ pg_strtoint64_safe(const char *s, Node *escontext) bool neg = false; /* skip leading spaces */ - while (*ptr && isspace((unsigned char) *ptr)) + while (isspace((unsigned char) *ptr)) ptr++; /* handle sign */ @@ -497,14 +521,17 @@ pg_strtoint64_safe(const char *s, Node *escontext) { firstdigit = ptr += 2; - while (*ptr) + while (1) { - if (isxdigit((unsigned char) *ptr)) + int8 digit = hexlookup[(unsigned char) *ptr]; + + if (likely(digit >= 0)) { if (unlikely(tmp > -(PG_INT64_MIN / 16))) goto out_of_range; - tmp = tmp * 16 + hexlookup[(unsigned char) *ptr++]; + tmp = tmp * 16 + digit; + ptr++; } else if (*ptr == '_') { @@ -521,14 +548,17 @@ pg_strtoint64_safe(const char *s, Node *escontext) { firstdigit = ptr += 2; - while (*ptr) + while (1) { - if (*ptr >= '0' && *ptr <= '7') + unsigned char digit = *ptr - '0'; + + if (likely(digit < 8)) { if (unlikely(tmp > -(PG_INT64_MIN / 8))) goto out_of_range; - tmp = tmp * 8 + (*ptr++ - '0'); + tmp = tmp * 8 + digit; + ptr++; } else if (*ptr == '_') { @@ -545,14 +575,17 @@ pg_strtoint64_safe(const char *s, Node *escontext) { firstdigit = ptr += 2; - while (*ptr) + while (1) { - if (*ptr >= '0' && *ptr <= '1') + unsigned char digit = *ptr - '0'; + + if (likely(digit < 2)) { if (unlikely(tmp > -(PG_INT64_MIN / 2))) goto out_of_range; - tmp = tmp * 2 + (*ptr++ - '0'); + tmp = tmp * 2 + digit; + ptr++; } else if (*ptr == '_') { @@ -569,14 +602,17 @@ pg_strtoint64_safe(const char *s, Node *escontext) { firstdigit = ptr; - while (*ptr) + while (1) { - if (isdigit((unsigned char) *ptr)) + unsigned char digit = *ptr - '0'; + + if (likely(digit < 10)) { if (unlikely(tmp > -(PG_INT64_MIN / 10))) goto out_of_range; - tmp = tmp * 10 + (*ptr++ - '0'); + tmp = tmp * 10 + digit; + ptr++; } else if (*ptr == '_') { @@ -598,7 +634,7 @@ pg_strtoint64_safe(const char *s, Node *escontext) goto invalid_syntax; /* allow trailing whitespace, but not other trailing chars */ - while (*ptr != '\0' && isspace((unsigned char) *ptr)) + while (isspace((unsigned char) *ptr)) ptr++; if (unlikely(*ptr != '\0'))