Skip to content
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
2 changes: 2 additions & 0 deletions embed.fnc
Original file line number Diff line number Diff line change
Expand Up @@ -4715,6 +4715,8 @@ S |void |inplace_aassign|NN OP *o
RST |bool |is_handle_constructor \
|NN const OP *o \
|I32 numargs
Ti |bool |is_standard_filehandle_name \
|NN const char *fhname
S |OP * |listkids |NULLOK OP *o
S |bool |looks_like_bool|NN const OP *o
S |OP * |modkids |NULLOK OP *o \
Expand Down
1 change: 1 addition & 0 deletions embed.h
Original file line number Diff line number Diff line change
Expand Up @@ -1435,6 +1435,7 @@
# define gen_constant_list(a) S_gen_constant_list(aTHX_ a)
# define inplace_aassign(a) S_inplace_aassign(aTHX_ a)
# define is_handle_constructor S_is_handle_constructor
# define is_standard_filehandle_name S_is_standard_filehandle_name
# define listkids(a) S_listkids(aTHX_ a)
# define looks_like_bool(a) S_looks_like_bool(aTHX_ a)
# define modkids(a,b) S_modkids(aTHX_ a,b)
Expand Down
4 changes: 4 additions & 0 deletions lib/B/Op_private.pm

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 27 additions & 7 deletions op.c
Original file line number Diff line number Diff line change
Expand Up @@ -712,17 +712,27 @@ Perl_no_bareword_allowed(pTHX_ OP *o)
o->op_private &= ~OPpCONST_STRICT; /* prevent warning twice about the same OP */
}

/*
Return true if the supplied string is the name of one of the built-in
filehandles.
*/

PERL_STATIC_INLINE bool
S_is_standard_filehandle_name(const char *fhname) {
return strEQ(fhname, "STDERR")
|| strEQ(fhname, "STDOUT")
|| strEQ(fhname, "STDIN")
|| strEQ(fhname, "_")
|| strEQ(fhname, "ARGV")
|| strEQ(fhname, "ARGVOUT")
|| strEQ(fhname, "DATA");
}

void
Perl_no_bareword_filehandle(pTHX_ const char *fhname) {
PERL_ARGS_ASSERT_NO_BAREWORD_FILEHANDLE;

if (strNE(fhname, "STDERR")
&& strNE(fhname, "STDOUT")
&& strNE(fhname, "STDIN")
&& strNE(fhname, "_")
&& strNE(fhname, "ARGV")
&& strNE(fhname, "ARGVOUT")
&& strNE(fhname, "DATA")) {
if (!is_standard_filehandle_name(fhname)) {
qerror(Perl_mess(aTHX_ "Bareword filehandle \"%s\" not allowed under 'no feature \"bareword_filehandles\"'", fhname));
}
}
Expand Down Expand Up @@ -14841,6 +14851,7 @@ Perl_ck_subr(pTHX_ OP *o)
CV *cv;
GV *namegv;
SV **const_class = NULL;
OP *const_op = NULL;

PERL_ARGS_ASSERT_CK_SUBR;

Expand Down Expand Up @@ -14870,20 +14881,29 @@ Perl_ck_subr(pTHX_ OP *o)
if (aop->op_type == OP_CONST) {
aop->op_private &= ~OPpCONST_STRICT;
const_class = &cSVOPx(aop)->op_sv;
const_op = aop;
}
else if (aop->op_type == OP_LIST) {
OP * const sib = OpSIBLING(cUNOPx(aop)->op_first);
if (sib && sib->op_type == OP_CONST) {
sib->op_private &= ~OPpCONST_STRICT;
const_class = &cSVOPx(sib)->op_sv;
const_op = sib;
}
}
/* make class name a shared cow string to speedup method calls */
/* constant string might be replaced with object, f.e. bigint */
if (const_class && SvPOK(*const_class)) {
assert(const_op);
STRLEN len;
const char* str = SvPV(*const_class, len);
if (len) {
if (!FEATURE_BAREWORD_FILEHANDLES_IS_ENABLED
&& !is_standard_filehandle_name(str)
&& (const_op->op_private & OPpCONST_BARE)) {
cvop->op_private |= OPpMETH_NO_BAREWORD_IO;
}

SV* const shared = newSVpvn_share(
str, SvUTF8(*const_class)
? -(SSize_t)len : (SSize_t)len,
Expand Down
Loading