Skip to content

Commit

Permalink
Remove spaces from a (copy of) a proto when used. The logic that uses…
Browse files Browse the repository at this point in the history
… prototypes assumes spaces were already gone, which may not be true if they were added via XS / set_prototype.
  • Loading branch information
PeterMartini authored and tonycoz committed Jun 25, 2013
1 parent 8c791ef commit d16269d
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 0 deletions.
28 changes: 28 additions & 0 deletions inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,34 @@ S_CvDEPTHp(const CV * const sv)
return &((XPVCV*)SvANY(sv))->xcv_depth;
}

/*
CvPROTO returns the prototype as stored, which is not necessarily what
the interpreter should be using. Specifically, the interpreter assumes
that spaces have been stripped, which has been the case if the prototype
was added by toke.c, but is generally not the case if it was added elsewhere.
Since we can't enforce the spacelessness at assignment time, this routine
provides a temporary copy at parse time with spaces removed.
I<orig> is the start of the original buffer, I<len> is the length of the
prototype and will be updated when this returns.
*/

PERL_STATIC_INLINE char *
S_strip_spaces(pTHX_ const char * orig, STRLEN * const len)
{
SV * tmpsv;
char * tmps;
tmpsv = newSVpvn_flags(orig, *len, SVs_TEMP);
tmps = SvPVX(tmpsv);
while ((*len)--) {
if (!isSPACE(*orig))
*tmps++ = *orig;
orig++;
}
*tmps = '\0';
*len = tmps - SvPVX(tmpsv);
return SvPVX(tmpsv);
}

/* ----------------------------- regexp.h ----------------------------- */

PERL_STATIC_INLINE struct regexp *
Expand Down
1 change: 1 addition & 0 deletions op.c
Original file line number Diff line number Diff line change
Expand Up @@ -10078,6 +10078,7 @@ Perl_ck_entersub_args_proto(pTHX_ OP *entersubop, GV *namegv, SV *protosv)
if (SvTYPE(protosv) == SVt_PVCV)
proto = CvPROTO(protosv), proto_len = CvPROTOLEN(protosv);
else proto = SvPV(protosv, proto_len);
proto = S_strip_spaces(aTHX_ proto, &proto_len);
proto_end = proto + proto_len;
aop = cUNOPx(entersubop)->op_first;
if (!aop->op_sibling)
Expand Down
1 change: 1 addition & 0 deletions toke.c
Original file line number Diff line number Diff line change
Expand Up @@ -7281,6 +7281,7 @@ Perl_yylex(pTHX)
STRLEN protolen = CvPROTOLEN(cv);
const char *proto = CvPROTO(cv);
bool optional;
proto = S_strip_spaces(aTHX_ proto, &protolen);
if (!protolen)
TERM(FUNC0SUB);
if ((optional = *proto == ';'))
Expand Down

0 comments on commit d16269d

Please sign in to comment.