summaryrefslogtreecommitdiff
path: root/perly.c
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2006-12-10 18:50:05 +0000
committerDave Mitchell <davem@fdisolutions.com>2006-12-10 18:50:05 +0000
commit2af555bf3f2b3ca8e114df3f5f680d40bd24d6bf (patch)
treeab3bfe43c56cfe0d9f676a1fb13e2614325893ee /perly.c
parentd5c6462ec54f07680e7532435b71727ae3075024 (diff)
downloadperl-2af555bf3f2b3ca8e114df3f5f680d40bd24d6bf.tar.gz
#28315 could crash when freeing ops with different pads
Add hook to parser to record current PL_comppad, then use this when popping ops off the parser stack after parser error p4raw-id: //depot/perl@29501
Diffstat (limited to 'perly.c')
-rw-r--r--perly.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/perly.c b/perly.c
index b8b582fc3b..fe9acc8bcf 100644
--- a/perly.c
+++ b/perly.c
@@ -332,6 +332,9 @@ Perl_yyparse (pTHX)
rule. */
int yylen;
+ /* keep track of which pad ops are currently using */
+ AV* comppad = PL_comppad;
+
#ifndef PERL_IN_MADLY_C
# ifdef PERL_MAD
if (PL_madskills)
@@ -573,6 +576,8 @@ Perl_yyparse (pTHX)
*++yyvsp = yyval;
+ comppad = PL_comppad;
+
#ifdef DEBUGGING
*++yynsp = (const char *)(yytname [yyr1[yyn]]);
#endif
@@ -669,9 +674,14 @@ Perl_yyparse (pTHX)
/* Pop the error token. */
YYPOPSTACK;
/* Pop the rest of the stack. */
+ PAD_RESTORE_LOCAL(comppad);
while (yyss < yyssp) {
YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp);
- if (yy_type_tab[yystos[*yyssp]] == toketype_opval) {
+ if (yy_type_tab[yystos[*yyssp]] == toketype_padval) {
+ comppad = yyvsp->padval;
+ PAD_RESTORE_LOCAL(comppad);
+ }
+ else if (yy_type_tab[yystos[*yyssp]] == toketype_opval) {
YYDPRINTF ((Perl_debug_log, "(freeing op)\n"));
op_free(yyvsp->opval);
}
@@ -696,6 +706,7 @@ Perl_yyparse (pTHX)
yyerrlab1:
yyerrstatus = 3; /* Each real token shifted decrements this. */
+ PAD_RESTORE_LOCAL(comppad);
for (;;) {
yyn = yypact[yystate];
if (yyn != YYPACT_NINF) {
@@ -712,7 +723,11 @@ Perl_yyparse (pTHX)
YYABORT;
YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp);
- if (yy_type_tab[yystos[*yyssp]] == toketype_opval) {
+ if (yy_type_tab[yystos[*yyssp]] == toketype_padval) {
+ comppad = yyvsp->padval;
+ PAD_RESTORE_LOCAL(comppad);
+ }
+ else if (yy_type_tab[yystos[*yyssp]] == toketype_opval) {
YYDPRINTF ((Perl_debug_log, "(freeing op)\n"));
op_free(yyvsp->opval);
}