diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Doc/Zsh/options.yo | 4 | ||||
-rw-r--r-- | Src/math.c | 34 | ||||
-rw-r--r-- | Src/utils.c | 5 | ||||
-rw-r--r-- | Test/C01arith.ztst | 12 |
5 files changed, 51 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog index 0bf106413..3b6365bcf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2007-02-10 Peter Stephenson <p.w.stephenson@ntlworld.com> + + 23165: Src/math.c, Src/utils.c, Doc/Zsh/options.yo: don't + try to parse base indicators in octal and raise error for + bases above 36. + 2007-02-10 Felix Rosencrantz <f.rosencrantz@gmail.com> * 23164: Src/builtin.c when PUSHD_SILENT is set, don't print anything from popd/pushd. diff --git a/Doc/Zsh/options.yo b/Doc/Zsh/options.yo index e1f3fc509..b929366c4 100644 --- a/Doc/Zsh/options.yo +++ b/Doc/Zsh/options.yo @@ -1101,6 +1101,10 @@ Interpret any integer constant beginning with a 0 as octal, per IEEE Std 1003.2-1992 (ISO 9945-2:1993). This is not enabled by default as it causes problems with parsing of, for example, date and time strings with leading zeroes. + +Sequences of digits indicating a numeric base such as the `tt(08)' +component in `tt(08#77)' are always interpreted as decimal, regardless +of leading zeroes. ) pindex(TYPESET_SILENT) item(tt(TYPESET_SILENT))( diff --git a/Src/math.c b/Src/math.c index 809999f9c..66d57fd53 100644 --- a/Src/math.c +++ b/Src/math.c @@ -216,17 +216,33 @@ lexconstant(void) lastbase = 16; return NUM; } - else if (isset(OCTALZEROES) && - (memchr(nptr, '.', strlen(nptr)) == NULL) && - idigit(*nptr)) { - yyval.u.l = zstrtol(ptr, &ptr, 0); - lastbase = 8; - return NUM; + else if (isset(OCTALZEROES)) + { + char *ptr2; + + /* + * Make sure this is a real octal constant; + * it can't be a base indication (always decimal) + * or a floating point number. + */ + for (ptr2 = nptr; idigit(*ptr2); ptr2++) + ; + + if (ptr2 > nptr && *ptr2 != '.' && *ptr2 != 'e' && + *ptr2 != 'E' && *ptr2 != '#') + { + yyval.u.l = zstrtol(ptr, &ptr, 0); + lastbase = 8; + return NUM; + } + nptr = ptr2; } } - - while (idigit(*nptr)) - nptr++; + else + { + while (idigit(*nptr)) + nptr++; + } if (*nptr == '.' || *nptr == 'e' || *nptr == 'E') { /* it's a float */ diff --git a/Src/utils.c b/Src/utils.c index 2ea8ba991..0e7a7d2bb 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -1803,7 +1803,10 @@ zstrtol(const char *s, char **t, int base) base = 8; } inp = s; - if (base <= 10) + if (base > 36) { + zerr("invalid base: %d", base); + return (zlong)0; + } else if (base <= 10) for (; *s >= '0' && *s < ('0' + base); s++) { if (trunc) continue; diff --git a/Test/C01arith.ztst b/Test/C01arith.ztst index 9867b5d9a..e4ddebc12 100644 --- a/Test/C01arith.ztst +++ b/Test/C01arith.ztst @@ -136,3 +136,15 @@ print $(( 5, (3 + 7, 4) )) 0:commas and parentheses, part 1 >4 + + (setopt octalzeroes; print $(( 08#77 ))) +0:octalzeroes doesn't affect bases +>63 + + print $(( 36#z )) +0:bases up to 36 work +>35 + + print $(( 37#z )) +1:bases beyond 36 don't work +?(eval):1: invalid base: 37 |