Skip to content
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

split pattern allows barewords under use strict 'subs' #16837

Open
p5pRT opened this issue Feb 4, 2019 · 9 comments
Open

split pattern allows barewords under use strict 'subs' #16837

p5pRT opened this issue Feb 4, 2019 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented Feb 4, 2019

Migrated from rt.perl.org#133822 (status was 'open')

Searchable as RT133822$

@p5pRT
Copy link
Author

p5pRT commented Feb 4, 2019

From @Grinnz

The first argument to split appears to allow a bareword and interprets it
as a string with no error, even with strict 'subs' active. This is at the
very least undocumented.

perl -E'use strict; say for split foo, "barfoobar"'

The unary + does not even affect the behavior.

perl -E'use strict; say for split +foo, "barfoobar"'

-Dan

(Perl)

@p5pRT
Copy link
Author

p5pRT commented Feb 5, 2019

From @tonycoz

On Mon, 04 Feb 2019 15​:09​:29 -0800, grinnz@​gmail.com wrote​:

The first argument to split appears to allow a bareword and interprets it
as a string with no error, even with strict 'subs' active. This is at the
very least undocumented.

perl -E'use strict; say for split foo, "barfoobar"'

The unary + does not even affect the behavior.

perl -E'use strict; say for split +foo, "barfoobar"'

Fix attached.

Tony

@p5pRT
Copy link
Author

p5pRT commented Feb 5, 2019

From @tonycoz

0001-perl-133822-check-strictness-on-split-bareword.patch
From 0b735a0ee01c105cf8ccedca77382e4eb7dad74e Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Tue, 5 Feb 2019 15:59:59 +1100
Subject: (perl #133822) check strictness on split bareword

Perl_ck_split was converting the OP_CONST into a PM without
checking the strictness flag.
---
 op.c           |  2 ++
 t/lib/croak/op | 10 ++++++++++
 2 files changed, 12 insertions(+)

diff --git a/op.c b/op.c
index 8a61b8b616..c33e6f6f5e 100644
--- a/op.c
+++ b/op.c
@@ -12834,6 +12834,8 @@ Perl_ck_split(pTHX_ OP *o)
     kid = cLISTOPo->op_first;
 
     if (kid->op_type != OP_MATCH || kid->op_flags & OPf_STACKED) {
+        if (kid->op_type == OP_CONST && (kid->op_private & OPpCONST_STRICT))
+            no_bareword_allowed(kid);
         /* remove match expression, and replace with new optree with
          * a match op at its head */
         op_sibling_splice(o, NULL, 1, NULL);
diff --git a/t/lib/croak/op b/t/lib/croak/op
index 5f31478860..4ad74f31c3 100644
--- a/t/lib/croak/op
+++ b/t/lib/croak/op
@@ -251,3 +251,13 @@ Type of arg 1 to pop must be array (not private hash) at - line 4, near "%a;"
 Type of arg 1 to shift must be array (not private hash) at - line 5, near "%a;"
 Type of arg 1 to unshift must be array (not private hash) at - line 6, near "1;"
 Execution of - aborted due to compilation errors.
+########
+# NAME split bareword
+use strict;
+my $x = "";
+my @x = split bareword, $x;
+my @x = split +bareword, $x;
+EXPECT
+Bareword "bareword" not allowed while "strict subs" in use at - line 3.
+Bareword "bareword" not allowed while "strict subs" in use at - line 4.
+Execution of - aborted due to compilation errors.
-- 
2.11.0

@p5pRT
Copy link
Author

p5pRT commented Feb 5, 2019

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Feb 5, 2019

From @hvds

On Mon, 04 Feb 2019 21​:01​:46 -0800, tonyc wrote​:

On Mon, 04 Feb 2019 15​:09​:29 -0800, grinnz@​gmail.com wrote​:

The first argument to split appears to allow a bareword and interprets it
as a string with no error, even with strict 'subs' active. This is at the
very least undocumented.

perl -E'use strict; say for split foo, "barfoobar"'

The unary + does not even affect the behavior.

perl -E'use strict; say for split +foo, "barfoobar"'

Fix attached.

Tony

I note that this bug has been present a long time (at least as far back as 5.10), so fixing it may cause substantial breakage. My inclination would be to document it, and look for a lower-risk way to make the fix available (eg starting with a deprecation warning).

Hugo

@p5pRT
Copy link
Author

p5pRT commented Feb 5, 2019

From @jkeenan

On Tue, 05 Feb 2019 11​:29​:06 GMT, hv wrote​:

On Mon, 04 Feb 2019 21​:01​:46 -0800, tonyc wrote​:

On Mon, 04 Feb 2019 15​:09​:29 -0800, grinnz@​gmail.com wrote​:

The first argument to split appears to allow a bareword and
interprets it
as a string with no error, even with strict 'subs' active. This is
at the
very least undocumented.

perl -E'use strict; say for split foo, "barfoobar"'

The unary + does not even affect the behavior.

perl -E'use strict; say for split +foo, "barfoobar"'

Fix attached.

Tony

I note that this bug has been present a long time (at least as far
back as 5.10), so fixing it may cause substantial breakage. My
inclination would be to document it, and look for a lower-risk way to
make the fix available (eg starting with a deprecation warning).

Hugo

+1 -- especially since we're only two weeks away from code freeze.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Feb 5, 2019

From @tonycoz

On Tue, 05 Feb 2019 03​:29​:06 -0800, hv wrote​:

On Mon, 04 Feb 2019 21​:01​:46 -0800, tonyc wrote​:

On Mon, 04 Feb 2019 15​:09​:29 -0800, grinnz@​gmail.com wrote​:

The first argument to split appears to allow a bareword and
interprets it
as a string with no error, even with strict 'subs' active. This is
at the
very least undocumented.

perl -E'use strict; say for split foo, "barfoobar"'

The unary + does not even affect the behavior.

perl -E'use strict; say for split +foo, "barfoobar"'

Fix attached.

Tony

I note that this bug has been present a long time (at least as far
back as 5.10), so fixing it may cause substantial breakage. My
inclination would be to document it, and look for a lower-risk way to
make the fix available (eg starting with a deprecation warning).

I wasn't planning on applying it before 5.31.

As a bug fix I'm not sure it needs a deprecation cycle.

Tony

@p5pRT
Copy link
Author

p5pRT commented Sep 11, 2019

From @tonycoz

On Tue, 05 Feb 2019 14​:29​:36 -0800, tonyc wrote​:

On Tue, 05 Feb 2019 03​:29​:06 -0800, hv wrote​:

On Mon, 04 Feb 2019 21​:01​:46 -0800, tonyc wrote​:

On Mon, 04 Feb 2019 15​:09​:29 -0800, grinnz@​gmail.com wrote​:

The first argument to split appears to allow a bareword and
interprets it
as a string with no error, even with strict 'subs' active. This is
at the
very least undocumented.

perl -E'use strict; say for split foo, "barfoobar"'

The unary + does not even affect the behavior.

perl -E'use strict; say for split +foo, "barfoobar"'

Fix attached.

Tony

I note that this bug has been present a long time (at least as far
back as 5.10), so fixing it may cause substantial breakage. My
inclination would be to document it, and look for a lower-risk way to
make the fix available (eg starting with a deprecation warning).

I wasn't planning on applying it before 5.31.

As a bug fix I'm not sure it needs a deprecation cycle.

Tony

Here's a deprecation patch.

Tony

@p5pRT
Copy link
Author

p5pRT commented Sep 11, 2019

From @tonycoz

0001-perl-133822-deprecate-split-bareword.patch
From 61135e4bdbcc08b4d0a342740ec9b24aff273dd5 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Tue, 5 Feb 2019 15:59:59 +1100
Subject: (perl #133822) deprecate split bareword

---
 op.c                    |  4 ++++
 pod/perldeprecation.pod | 10 ++++++++++
 pod/perldiag.pod        |  6 ++++++
 t/lib/warnings/op       |  9 +++++++++
 4 files changed, 29 insertions(+)

diff --git a/op.c b/op.c
index 86251047b6..b133e3964e 100644
--- a/op.c
+++ b/op.c
@@ -13242,6 +13242,10 @@ Perl_ck_split(pTHX_ OP *o)
     kid = cLISTOPo->op_first;
 
     if (kid->op_type != OP_MATCH || kid->op_flags & OPf_STACKED) {
+        if (kid->op_type == OP_CONST && (kid->op_private & OPpCONST_STRICT)) {
+            Perl_ck_warner_d(aTHX_ packWARN(WARN_DEPRECATED),
+                             "Bareword pattern for split() under strict \"subs\" deprecated");
+        }
         /* remove match expression, and replace with new optree with
          * a match op at its head */
         op_sibling_splice(o, NULL, 1, NULL);
diff --git a/pod/perldeprecation.pod b/pod/perldeprecation.pod
index c96be0c671..6ce9c78d8b 100644
--- a/pod/perldeprecation.pod
+++ b/pod/perldeprecation.pod
@@ -14,6 +14,16 @@ features are available.
 The deprecated features will be grouped by the version of Perl in
 which they will be removed.
 
+=head2 Perl 5.36
+
+=head3 Bareword pattern for split() under strict "subs"
+
+The L<perlfunc/split> operator currently allows (with a deprecation
+warning) a bareword as the first argument to split.  This will become
+an error in Perl 5.36.
+
+See L<https://rt.perl.org/Ticket/Display.html?id=133822> for details.
+
 =head2 Perl 5.32
 
 =head3 Constants from lexical variables potentially modified elsewhere
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 2fa4b62257..b52469d7fc 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -557,6 +557,12 @@ double-colon.  Write C<require ::Foo::Bar> as  C<require Foo::Bar> instead.
 subroutine identifier, in curly brackets or to the left of the "=>"
 symbol.  Perhaps you need to predeclare a subroutine?
 
+=item Bareword pattern for split() under strict "subs" deprecated
+
+(D deprecated) Perl has erroneously long allowed a bareword as the
+PATTERN argyment to L<perlfunc/split>.  This will be disallowed in
+perl 5.36.
+
 =item Bareword "%s" refers to nonexistent package
 
 (W bareword) You used a qualified bareword of the form C<Foo::>, but the
diff --git a/t/lib/warnings/op b/t/lib/warnings/op
index 4d0b002a15..3314d21384 100644
--- a/t/lib/warnings/op
+++ b/t/lib/warnings/op
@@ -2063,3 +2063,12 @@ Useless use of a constant (32) in void context at - line 11.
 Useless use of a constant (41) in void context at - line 14.
 Useless use of a constant (42) in void context at - line 14.
 Useless use of a constant (51) in void context at - line 16.
+########
+# NAME split bareword
+use strict;
+my $x = "";
+my @x = split bareword, $x;
+my @x = split +bareword, $x;
+EXPECT
+Bareword pattern for split() under strict "subs" deprecated - line 3.
+Bareword pattern for split() under strict "subs" deprecated - line 4.
-- 
2.11.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants