summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2014-08-22 14:52:46 -0400
committerJarkko Hietaniemi <jhi@iki.fi>2014-08-22 15:18:49 -0400
commit9ff909cfc2bd7949d8ac29824e865f43be5c444c (patch)
tree0a4acc5e33b5a1370d158751d040068f1e26cc98
parent1b9a108c3fb045814d05d8ad470bbbceec7c8543 (diff)
downloadperl-9ff909cfc2bd7949d8ac29824e865f43be5c444c.tar.gz
Fix the PEEK_INFNAN (wrong macro arg name).
Also rename as INFNAN_PEEK, to match HEXFP_PEEK. Add "send" pointer to INFNAN_PEEK to guard againt past-the-buffer peeking. HEXFP_PEEK doesn't easily lend itself to "send" pointer because of it's calling environment doesn't have one.
-rw-r--r--numeric.c19
-rw-r--r--toke.c9
2 files changed, 16 insertions, 12 deletions
diff --git a/numeric.c b/numeric.c
index ce8bbdd3da..26d795c5d8 100644
--- a/numeric.c
+++ b/numeric.c
@@ -587,11 +587,14 @@ Perl_grok_number(pTHX_ const char *pv, STRLEN len, UV *valuep)
}
/* Peek ahead to see whether this could be Inf/NaN/qNaN/snan/1.#INF */
-#define PEEK_INFNAN(d) \
- (isALPHA_FOLD_EQ(*s, 'I') || isALPHA_FOLD_EQ(*s, 'N')) || \
- ((isALPHA_FOLD_EQ(*s, 'Q') || isALPHA_FOLD_EQ(*s, 'S')) && \
- isALPHA_FOLD_EQ(s[1], 'N')) || \
- (*s == '1' && ((s[1] == '.' && s[2] == '#') || s[1] == '#'))
+#define INFNAN_PEEK(s, send) \
+ (s < send && \
+ ((isALPHA_FOLD_EQ(*s, 'I') || isALPHA_FOLD_EQ(*s, 'N')) || \
+ ((s + 4) < send && \
+ (isALPHA_FOLD_EQ(*s, 'Q') || isALPHA_FOLD_EQ(*s, 'S')) && \
+ isALPHA_FOLD_EQ(s[1], 'N')) || \
+ ((s + 5) < send && \
+ (*s == '1' && ((s[1] == '.' && s[2] == '#') || s[1] == '#')))))
/*
=for apidoc grok_infnan
@@ -839,7 +842,7 @@ Perl_grok_number_flags(pTHX_ const char *pv, STRLEN len, UV *valuep, U32 flags)
return 0;
}
else {
- if (PEEK_INFNAN(d)) {
+ if (INFNAN_PEEK(d, send)) {
int infnan = Perl_grok_infnan(&d, send);
if ((infnan & IS_NUMBER_INFINITY)) {
numtype |= infnan;
@@ -1184,9 +1187,9 @@ Perl_my_atof2(pTHX_ const char* orig, NV* value)
}
}
#elif defined(HAS_STRTOD)
- if (PEEK_INFNAN(s)) {
+ if (INFNAN_PEEK(s, send)) {
/* The native strtod() may not get all the possible
- * inf/nan strings PEEK_INFNAN() recognizes. */
+ * inf/nan strings INFNAN_PEEK() recognizes. */
char* endp;
NV nv = Perl_strtod(p, &endp);
if (p != endp) {
diff --git a/toke.c b/toke.c
index dee6f42ff1..f855f696ed 100644
--- a/toke.c
+++ b/toke.c
@@ -114,6 +114,11 @@ static const char* const ident_too_long = "Identifier too long";
#define SPACE_OR_TAB(c) isBLANK_A(c)
+#define HEXFP_PEEK(s) \
+ (((s[0] == '.') && \
+ (isXDIGIT(s[1]) || isALPHA_FOLD_EQ(s[1], 'p'))) || \
+ isALPHA_FOLD_EQ(s[0], 'p'))
+
/* LEX_* are values for PL_lex_state, the state of the lexer.
* They are arranged oddly so that the guard on the switch statement
* can get by with a single comparison (if the compiler is smart enough).
@@ -9980,10 +9985,6 @@ Perl_scan_num(pTHX_ const char *start, YYSTYPE* lvalp)
/* this could be hexfp, but peek ahead
* to avoid matching ".." */
-#define HEXFP_PEEK(s) \
- (((s[0] == '.') && \
- (isXDIGIT(s[1]) || isALPHA_FOLD_EQ(s[1], 'p'))) \
- || isALPHA_FOLD_EQ(s[0], 'p'))
if (UNLIKELY(HEXFP_PEEK(s))) {
goto out;
}