diff options
author | Tony Cook <tony@develop-help.com> | 2020-12-08 14:28:29 +1100 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2021-01-07 08:43:15 +0000 |
commit | bdd419192a8b2ab26be9cf5b4b8d7fe6f66b144c (patch) | |
tree | 68a39c20aae79f408a4a4d3a83071acf51a08d55 | |
parent | 9aff587fd2011ad85668efc30ed29e794fdb484e (diff) | |
download | perl-bdd419192a8b2ab26be9cf5b4b8d7fe6f66b144c.tar.gz |
skip trying to constant fold an incomplete op tree
This code would try to constant fold an op tree like
relop
+- null
+- constant
which would underflow the stack, potentially crashing perl.
This is intended as a quick fix rather than as a complete
solution.
Fixes #18380
(cherry picked from commit 08be3ef7f1190d94279ad0b3e13519ac8dc3b0ec)
-rw-r--r-- | op.c | 2 | ||||
-rw-r--r-- | t/op/cmpchain.t | 17 |
2 files changed, 11 insertions, 8 deletions
@@ -5605,7 +5605,7 @@ Perl_cmpchain_finish(pTHX_ OP *ch) cmpop->op_private = 2; cmpop = CHECKOP(cmpoptype, cmpop); if(!cmpop->op_next && cmpop->op_type == cmpoptype) - cmpop = fold_constants(op_integerize(op_std_init(cmpop))); + cmpop = op_integerize(op_std_init(cmpop)); condop = condop ? newLOGOP(OP_CMPCHAIN_AND, 0, cmpop, condop) : cmpop; if (!nextrightarg) diff --git a/t/op/cmpchain.t b/t/op/cmpchain.t index 92a2f4133d..236d5f9a83 100644 --- a/t/op/cmpchain.t +++ b/t/op/cmpchain.t @@ -14,13 +14,6 @@ my @nceqop = qw(<=> cmp ~~); my @chrelop = qw(< > <= >= lt gt le ge); my @ncrelop = qw(isa); -plan tests => @nceqop*@nceqop + 2*@cheqop*@nceqop + 2*@cheqop*@cheqop*@nceqop + - @ncrelop*@ncrelop + 2*@chrelop*@ncrelop + 2*@chrelop*@chrelop*@ncrelop + - - @cheqop*@cheqop + @chrelop*@chrelop + - @cheqop*@cheqop*@cheqop + @chrelop*@chrelop*@chrelop + - (9 + 6*9)*13; - foreach my $c0 (@nceqop) { foreach my $c1 (@nceqop) { is eval("sub { \$a $c0 \$b $c1 \$c }"), undef, @@ -168,3 +161,13 @@ foreach( "operand evaluation order"; } } + +# https://github.com/Perl/perl5/issues/18380 +fresh_perl_is(<<'CODE', "", {}, "stack underflow"); +no warnings "uninitialized"; +my $v; +1 < $v < 2; +2 < $v < 3; +CODE + +done_testing(); |