summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Garcia-Suarez <rgarciasuarez@gmail.com>2002-12-06 21:27:55 +0000
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2002-12-06 21:27:55 +0000
commit8edd5f42cf54cdbf0218037ce0d38a9e2e2d58d9 (patch)
tree667f471dd4f2cb40fd0bf4d3a45b6927add1d26e
parenta33bf49bf7b1088ee6ac580e9e39716ad87ae72a (diff)
downloadperl-8edd5f42cf54cdbf0218037ce0d38a9e2e2d58d9.tar.gz
Fix two cases of buffer overflow in the lexer.
p4raw-id: //depot/perl@18251
-rw-r--r--t/comp/parser.t17
-rw-r--r--toke.c24
2 files changed, 22 insertions, 19 deletions
diff --git a/t/comp/parser.t b/t/comp/parser.t
index ab43e7340e..40ae5f18cf 100644
--- a/t/comp/parser.t
+++ b/t/comp/parser.t
@@ -9,7 +9,7 @@ BEGIN {
}
require "./test.pl";
-plan( tests => 10 );
+plan( tests => 12 );
eval '%@x=0;';
like( $@, qr/^Can't modify hash dereference in repeat \(x\)/, '%@x=0' );
@@ -51,3 +51,18 @@ like( $@, qr/error/, 'lexical block discarded by yacc' );
# bug #18573, used to corrupt memory
eval q{ "\c" };
like( $@, qr/^Missing control char name in \\c/, q("\c" string) );
+
+# two tests for memory corruption problems in the said variables
+# (used to dump core or produce strange results)
+
+is( "\Q\Q\Q\Q\Q\Q\Q\Q\Q\Q\Q\Q\Qa", "a", "PL_lex_casestack" );
+
+eval {
+{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
+{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}
+};
+is( $@, '', 'PL_lex_brackstack' );
diff --git a/toke.c b/toke.c
index 1abf12194e..cb8fbea150 100644
--- a/toke.c
+++ b/toke.c
@@ -424,8 +424,8 @@ Perl_lex_start(pTHX_ SV *line)
SAVEPPTR(PL_last_uni);
SAVEPPTR(PL_linestart);
SAVESPTR(PL_linestr);
- SAVEPPTR(PL_lex_brackstack);
- SAVEPPTR(PL_lex_casestack);
+ SAVEGENERICPV(PL_lex_brackstack);
+ SAVEGENERICPV(PL_lex_casestack);
SAVEDESTRUCTOR_X(restore_rsfp, PL_rsfp);
SAVESPTR(PL_lex_stuff);
SAVEI32(PL_lex_defer);
@@ -440,8 +440,6 @@ Perl_lex_start(pTHX_ SV *line)
PL_lex_brackets = 0;
New(899, PL_lex_brackstack, 120, char);
New(899, PL_lex_casestack, 12, char);
- SAVEFREEPV(PL_lex_brackstack);
- SAVEFREEPV(PL_lex_casestack);
PL_lex_casemods = 0;
*PL_lex_casestack = '\0';
PL_lex_dojoin = 0;
@@ -1052,8 +1050,8 @@ S_sublex_push(pTHX)
SAVEPPTR(PL_last_uni);
SAVEPPTR(PL_linestart);
SAVESPTR(PL_linestr);
- SAVEPPTR(PL_lex_brackstack);
- SAVEPPTR(PL_lex_casestack);
+ SAVEGENERICPV(PL_lex_brackstack);
+ SAVEGENERICPV(PL_lex_casestack);
PL_linestr = PL_lex_stuff;
PL_lex_stuff = Nullsv;
@@ -1068,8 +1066,6 @@ S_sublex_push(pTHX)
PL_lex_brackets = 0;
New(899, PL_lex_brackstack, 120, char);
New(899, PL_lex_casestack, 12, char);
- SAVEFREEPV(PL_lex_brackstack);
- SAVEFREEPV(PL_lex_casestack);
PL_lex_casemods = 0;
*PL_lex_casestack = '\0';
PL_lex_starts = 0;
@@ -2279,11 +2275,7 @@ Perl_yylex(pTHX)
return ')';
}
if (PL_lex_casemods > 10) {
- char* newlb = Renew(PL_lex_casestack, PL_lex_casemods + 2, char);
- if (newlb != PL_lex_casestack) {
- SAVEFREEPV(newlb);
- PL_lex_casestack = newlb;
- }
+ Renew(PL_lex_casestack, PL_lex_casemods + 2, char);
}
PL_lex_casestack[PL_lex_casemods++] = *s;
PL_lex_casestack[PL_lex_casemods] = '\0';
@@ -3117,11 +3109,7 @@ Perl_yylex(pTHX)
leftbracket:
s++;
if (PL_lex_brackets > 100) {
- char* newlb = Renew(PL_lex_brackstack, PL_lex_brackets + 1, char);
- if (newlb != PL_lex_brackstack) {
- SAVEFREEPV(newlb);
- PL_lex_brackstack = newlb;
- }
+ Renew(PL_lex_brackstack, PL_lex_brackets + 10, char);
}
switch (PL_expect) {
case XTERM: