Fix buffer overflow with overlong identifiers
authorFather Chrysostomos <sprout@cpan.org>
Mon, 9 Sep 2013 07:35:38 +0000 (00:35 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 9 Sep 2013 07:52:07 +0000 (00:52 -0700)
This was introduced by commit 32833930e32dc in 5.17.10.

$  ./perl -Ilib -e Foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
Identifier too long at -e line 1.
Segmentation fault: 11

(That was an amusing use of macro parentheses for the while condition,
at least while it lasted.)

t/comp/parser.t
toke.c

index 569ecd7..6578c74 100644 (file)
@@ -8,7 +8,7 @@ BEGIN {
     chdir 't';
 }
 
-print "1..166\n";
+print "1..167\n";
 
 sub failed {
     my ($got, $expected, $name) = @_;
@@ -487,6 +487,14 @@ BEGIN{ ${"_<".__FILE__} = \1 }
 is __FILE__, $file,
     'no __FILE__ corruption when setting CopFILESV to a ref';
 
+eval 'Fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo'
+    .'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo'
+    .'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo'
+    .'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo'
+    .'oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo'
+    .'ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo';
+like $@, "^Identifier too long at ", 'ident buffer overflow';
+
 # Add new tests HERE (above this line)
 
 # bug #74022: Loop on characters in \p{OtherIDContinue}
diff --git a/toke.c b/toke.c
index e738311..1e83419 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -9316,7 +9316,7 @@ S_parse_ident(pTHX_ char **s, char **d, char * const e, int allow_package, bool
         else if ( isWORDCHAR_A(**s) ) {
             do {
                 *(*d)++ = *(*s)++;
-            } while isWORDCHAR_A(**s);
+            } while (isWORDCHAR_A(**s) && *d < e);
         }
         else if (allow_package && **s == '\'' && isIDFIRST_lazy_if(*s+1,is_utf8)) {
             *(*d)++ = ':';