Skip to content

Commit 139cae9

Browse files
committed
readline ARGV: don't try to open '|-' or '-|' and warn
This has no effect on in-place editing nor on the <<>> operator. Later modified to ignore leading/trailing space when checking the name. Fixes #21176
1 parent 5d7d794 commit 139cae9

File tree

6 files changed

+62
-6
lines changed

6 files changed

+62
-6
lines changed

doio.c

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,23 @@ static const MGVTBL argvout_vtbl =
13581358
NULL /* svt_local */
13591359
};
13601360

1361+
static bool
1362+
S_is_fork_open(const char *name) {
1363+
/* return true if name matches /^\A\s*(\|-|\-|)\s*\z/ */
1364+
while (isSPACE(*name))
1365+
name++;
1366+
if ((name[0] != '|' || name[1] != '-')
1367+
&& (name[0] != '-' || name[1] != '|')) {
1368+
return false;
1369+
}
1370+
name += 2;
1371+
1372+
while (isSPACE(*name))
1373+
name++;
1374+
1375+
return *name == 0;
1376+
}
1377+
13611378
PerlIO *
13621379
Perl_nextargv(pTHX_ GV *gv, bool nomagicopen)
13631380
{
@@ -1400,11 +1417,22 @@ Perl_nextargv(pTHX_ GV *gv, bool nomagicopen)
14001417
SvSETMAGIC(GvSV(gv));
14011418
PL_oldname = SvPVx(GvSV(gv), oldlen);
14021419
if (LIKELY(!PL_inplace)) {
1403-
if (nomagicopen
1404-
? do_open6(gv, "<", 1, NULL, &GvSV(gv), 1)
1405-
: do_open6(gv, PL_oldname, oldlen, NULL, NULL, 0)
1406-
) {
1407-
return IoIFP(GvIOp(gv));
1420+
if (nomagicopen) {
1421+
if (do_open6(gv, "<", 1, NULL, &GvSV(gv), 1)) {
1422+
return IoIFP(GvIOp(gv));
1423+
}
1424+
}
1425+
else {
1426+
if (is_fork_open(PL_oldname)) {
1427+
Perl_ck_warner_d(aTHX_ packWARN(WARN_INPLACE),
1428+
"Forked open '%s' not meaningful in <>",
1429+
PL_oldname);
1430+
continue;
1431+
}
1432+
1433+
if ( do_open6(gv, PL_oldname, oldlen, NULL, NULL, 0) ) {
1434+
return IoIFP(GvIOp(gv));
1435+
}
14081436
}
14091437
}
14101438
else {

embed.fnc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4042,6 +4042,7 @@ S |void |exec_failed |NN const char *cmd \
40424042
|int do_report
40434043
RS |bool |ingroup |Gid_t testgid \
40444044
|bool effective
4045+
ST |bool |is_fork_open |NN const char *name
40454046
S |bool |openn_cleanup |NN GV *gv \
40464047
|NN IO *io \
40474048
|NULLOK PerlIO *fp \

embed.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,7 @@
11631163
# define argvout_final(a,b,c) S_argvout_final(aTHX_ a,b,c)
11641164
# define exec_failed(a,b,c) S_exec_failed(aTHX_ a,b,c)
11651165
# define ingroup(a,b) S_ingroup(aTHX_ a,b)
1166+
# define is_fork_open S_is_fork_open
11661167
# define openn_cleanup(a,b,c,d,e,f,g,h,i,j,k,l,m) S_openn_cleanup(aTHX_ a,b,c,d,e,f,g,h,i,j,k,l,m)
11671168
# define openn_setup(a,b,c,d,e,f) S_openn_setup(aTHX_ a,b,c,d,e,f)
11681169
# endif

pod/perldiag.pod

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2604,6 +2604,13 @@ same name?
26042604
iterate multiple values at a time. This syntax is currently experimental
26052605
and its behaviour may change in future releases of Perl.
26062606

2607+
=item Forked open '%s' not meaningful in <>
2608+
2609+
(S inplace) You had C<|-> or C<-|> in C<@ARGV> and tried to use C<< <>
2610+
>> to read from it.
2611+
2612+
Previously this would fork and produce a confusing error message.
2613+
26072614
=item Format not terminated
26082615

26092616
(F) A format must be terminated by a line with a solitary dot. Perl got

proto.h

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

t/io/argv.t

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ BEGIN {
66
set_up_inc('../lib');
77
}
88

9-
plan(tests => 37);
9+
plan(tests => 45);
1010

1111
my ($devnull, $no_devnull);
1212

@@ -252,6 +252,20 @@ close IN;
252252
unlink "tmpIo_argv3.tmp";
253253
**PROG**
254254

255+
{
256+
my $warn;
257+
local $SIG{__WARN__} = sub { $warn = "@_" };
258+
for my $op ("|-", "-|") {
259+
for my $forked ($op, " $op", "$op ", " $op ") {
260+
@ARGV = ( $forked );
261+
undef $warn;
262+
while (<>) {}
263+
like($warn, qr/^Forked open '\Q$forked\E' not meaningful in <>/,
264+
"check for warning for $forked");
265+
}
266+
}
267+
}
268+
255269
# This used to fail an assertion.
256270
# The tricks with *x and $x are to make PL_argvgv point to a freed SV when
257271
# the readline op does SvREFCNT_inc on it. undef *x clears the scalar slot

0 commit comments

Comments
 (0)