aboutsummaryrefslogtreecommitdiffstats
path: root/int_array.c
diff options
context:
space:
mode:
Diffstat (limited to 'int_array.c')
-rw-r--r--int_array.c95
1 files changed, 58 insertions, 37 deletions
diff --git a/int_array.c b/int_array.c
index a8de3d55..e7913dea 100644
--- a/int_array.c
+++ b/int_array.c
@@ -89,6 +89,25 @@ is_integer(NODE *symbol, NODE *subs)
if (subs == Nnull_string || do_mpfr)
return NULL;
+ /*
+ * Protect against MAYBE_NUM values where the string may not regenerate
+ * correctly. There could be white space and/or a non-decimal value.
+ * If stfmt is not STFMT_UNUSED, it means that the string value was
+ * generated using CONVFMT or OFMT, so there is no info there.
+ */
+ if ((subs->flags & STRCUR) != 0 && subs->stfmt == STFMT_UNUSED) {
+ char *cp = subs->stptr;
+
+ if ( subs->stlen == 0
+ || cp[0] == '0'
+ || isspace((unsigned char) cp[0])
+ || isspace((unsigned char) cp[subs->stlen - 1])
+ || ( subs->stlen >= 2
+ && (cp[0] == '-' || cp[0] == '+')
+ && cp[1] == '0'))
+ return NULL;
+ }
+
if ((subs->flags & NUMINT) != 0)
return & success_node;
@@ -107,49 +126,51 @@ is_integer(NODE *symbol, NODE *subs)
* a[-3]=1; print "-3" in a -- true
*/
- if ((subs->flags & (STRING|STRCUR)) != 0) {
- char *cp = subs->stptr, *cpend, *ptr;
- char save;
- size_t len = subs->stlen;
-
- if (len == 0 || (! isdigit((unsigned char) *cp) && *cp != '-'))
- return NULL;
- if (len > 1 &&
- ((*cp == '0') /* "00", "011" .. */
- || (*cp == '-' && *(cp + 1) == '0') /* "-0", "-011" .. */
- )
- )
- return NULL;
- if (len == 1 && *cp != '-') { /* single digit */
- subs->numbr = (long) (*cp - '0');
- if ((subs->flags & MAYBE_NUM) != 0) {
- subs->flags &= ~MAYBE_NUM;
- subs->flags |= NUMBER;
- }
- subs->flags |= (NUMCUR|NUMINT);
- return & success_node;
- }
+ /* must be a STRING */
+ char *cp = subs->stptr, *cpend, *ptr;
+ char save;
+ size_t len = subs->stlen;
- cpend = cp + len;
- save = *cpend;
- *cpend = '\0';
+ if (len == 0 || (! isdigit((unsigned char) *cp) && *cp != '-'))
+ return NULL;
- errno = 0;
- l = strtol(cp, & ptr, 10);
- *cpend = save;
- if (errno != 0 || ptr != cpend)
- return NULL;
- subs->numbr = l;
+ if (len > 1 &&
+ ((*cp == '0') /* "00", "011" .. */
+ || (*cp == '-' && *(cp + 1) == '0') /* "-0", "-011" .. */
+ )
+ )
+ return NULL;
+ if (len == 1 && *cp != '-') { /* single digit */
+ subs->numbr = (long) (*cp - '0');
if ((subs->flags & MAYBE_NUM) != 0) {
- subs->flags &= ~MAYBE_NUM;
+ subs->flags &= ~(MAYBE_NUM|STRING);
subs->flags |= NUMBER;
}
- subs->flags |= NUMCUR;
- if (l <= INT32_MAX && l >= INT32_MIN) {
- subs->flags |= NUMINT;
- return & success_node;
- }
+ subs->flags |= (NUMCUR|NUMINT);
+ return & success_node;
+ }
+
+ cpend = cp + len;
+ save = *cpend;
+ *cpend = '\0';
+
+ errno = 0;
+ l = strtol(cp, & ptr, 10);
+ *cpend = save;
+ if (errno != 0 || ptr != cpend)
+ return NULL;
+
+ subs->numbr = l;
+ if ((subs->flags & MAYBE_NUM) != 0) {
+ subs->flags &= ~(MAYBE_NUM|STRING);
+ subs->flags |= NUMBER;
}
+ subs->flags |= NUMCUR;
+ if (l <= INT32_MAX && l >= INT32_MIN) {
+ subs->flags |= NUMINT;
+ return & success_node;
+ }
+
return NULL;
}