Skip to content

Commit d709612

Browse files
committed
fixup correct handling of slurpy hash on odd number of elements
1 parent 9a82559 commit d709612

File tree

2 files changed

+20
-8
lines changed

2 files changed

+20
-8
lines changed

pp.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7984,11 +7984,14 @@ PP(pp_multiparam)
79847984
while(argc) {
79857985
SV **svp;
79867986

7987-
svp = av_fetch(defav, parami, FALSE); parami++;
7987+
svp = av_fetch(defav, parami, FALSE); parami++; argc--;
79887988
SV *name = svp ? *svp : &PL_sv_undef;
7989-
svp = av_fetch(defav, parami, FALSE); parami++;
7990-
SV *val = svp ? *svp : &PL_sv_undef;
7991-
argc -= 2;
7989+
7990+
SV *val = NULL;
7991+
if(argc) {
7992+
svp = av_fetch(defav, parami, FALSE); parami++; argc--;
7993+
val = svp ? *svp : &PL_sv_undef;
7994+
}
79927995

79937996
STRLEN namelen;
79947997
const char *namepv = SvPV(name, namelen);
@@ -8017,6 +8020,9 @@ PP(pp_multiparam)
80178020
if (UNLIKELY(TAINT_get) && !SvTAINTED(val))
80188021
TAINT_NOT;
80198022

8023+
if(!val)
8024+
val = &PL_sv_undef;
8025+
80208026
SvPADSTALE_off(*padentry);
80218027
SvSetMagicSV(*padentry, val);
80228028
}
@@ -8026,18 +8032,21 @@ PP(pp_multiparam)
80268032
assert(TAINTING_get || !TAINT_get);
80278033
if (UNLIKELY(TAINT_get) && !SvTAINTED(name))
80288034
TAINT_NOT;
8029-
if (UNLIKELY(TAINT_get) && !SvTAINTED(val))
8030-
TAINT_NOT;
8031-
80328035
av_push(av, newSVsv(name));
8033-
av_push(av, newSVsv(val));
8036+
8037+
if(val) {
8038+
if (UNLIKELY(TAINT_get) && !SvTAINTED(val))
8039+
TAINT_NOT;
8040+
av_push(av, newSVsv(val));
8041+
}
80348042
}
80358043
else if(slurpypad && slurpy == '%') {
80368044
HV *hv = (HV *)*slurpypad;
80378045

80388046
if (UNLIKELY(SvGMAGICAL(name)))
80398047
name = sv_mortalcopy(name);
80408048

8049+
assert(val); /* this must have passed the argc parity check */
80418050
if (UNLIKELY(TAINT_get) && !SvTAINTED(val))
80428051
TAINT_NOT;
80438052
hv_store_ent(hv, name, newSVsv(val), 0);

t/op/signatures.t

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -948,10 +948,13 @@ is eval("tnamed03(12, 34, x => 'X', y => 'Y')"), "a=12 b=34 x=X y=Y";
948948
sub tnamed04 (:$x, :$y, @rest) { "x=$x y=$y <@rest>"; }
949949
is prototype(\&tnamed04), undef;
950950
is eval("tnamed04(w => 'W', x => 'X', y => 'Y', z => 'Z')"), "x=X y=Y <w W z Z>";
951+
is eval("tnamed04(w => 'W', x => 'X', y => 'Y', 'single')"), "x=X y=Y <w W single>";
951952

952953
sub tnamed05 (:$x, :$y, %rest) { "x=$x y=$y " . join(",", map { "$_=$rest{$_}" } sort keys %rest); }
953954
is prototype(\&tnamed05), undef;
954955
is eval("tnamed05(w => 'W', x => 'X', y => 'Y', z => 'Z')"), "x=X y=Y w=W,z=Z";
956+
is eval("tnamed05(w => 'W', x => 'X', y => 'Y', 'single')"), undef;
957+
like $@, qr{^Odd name/value argument for subroutine 'main::tnamed05' at };
955958

956959
sub t085
957960
(

0 commit comments

Comments
 (0)