diff options
author | Dave Mitchell <davem@fdisolutions.com> | 2006-12-10 18:50:05 +0000 |
---|---|---|
committer | Dave Mitchell <davem@fdisolutions.com> | 2006-12-10 18:50:05 +0000 |
commit | 2af555bf3f2b3ca8e114df3f5f680d40bd24d6bf (patch) | |
tree | ab3bfe43c56cfe0d9f676a1fb13e2614325893ee /perly.c | |
parent | d5c6462ec54f07680e7532435b71727ae3075024 (diff) | |
download | perl-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.c | 19 |
1 files changed, 17 insertions, 2 deletions
@@ -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); } |