Skip to content

signatures: don't leak an OP_NULL for a '$ =' sigscalarelem #23203

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions op.c
Original file line number Diff line number Diff line change
Expand Up @@ -16543,19 +16543,22 @@ Perl_subsignature_append_positional(pTHX_ OP *varop, OPCODE defmode, OP *defexpr
if(defexpr) {
signature->optelems++;

I32 flags = 0;
if(defmode == OP_DORASSIGN)
flags |= OPpARG_IF_UNDEF << 8;
if(defmode == OP_ORASSIGN)
flags |= OPpARG_IF_FALSE << 8;

if(defexpr->op_type == OP_NULL && !(defexpr->op_flags & OPf_KIDS))
{
/* caller passed in newOP(OP_NULL, 0), so we should not leak it */
op_free(defexpr);

/* handle '$=' special case */
if(varop)
yyerror("Optional parameter lacks default expression");
}
else {
I32 flags = 0;
if(defmode == OP_DORASSIGN)
flags |= OPpARG_IF_UNDEF << 8;
if(defmode == OP_ORASSIGN)
flags |= OPpARG_IF_FALSE << 8;

/* a normal '=default' expression */
OP *defop = newARGDEFELEMOP(flags, defexpr, argix);

Expand Down
5 changes: 5 additions & 0 deletions pod/perldelta.pod
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,11 @@ Class initializers and C<ADJUST> blocks, per L<perlclass>, that
called C<last> or other loop exits would crash perl. Same cause as
for [GH #16608].

=item *

Prevent a signature parameter of the form C<$ => from leaking an OP at
compile-time. [GH #23187]

=back

=head1 Known Problems
Expand Down
Loading