summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Garcia-Suarez <rgarciasuarez@gmail.com>2002-10-29 20:37:31 +0000
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2002-10-29 20:37:31 +0000
commit904d85c5b9ccc833788234557fda3bc74a77ca8b (patch)
treed3a173b0ef63342d042d4082a467b71e0c32401f
parentb8370f2a62ce28c9808787355d168ac28a1aaa1c (diff)
downloadperl-904d85c5b9ccc833788234557fda3bc74a77ca8b.tar.gz
Partial fix of bug [perl #17589] : prevent the parser to
segfault when encountering the erroneous construct "sub;". p4raw-id: //depot/perl@18072
-rw-r--r--pod/perldiag.pod5
-rwxr-xr-xt/op/anonsub.t30
-rw-r--r--toke.c2
3 files changed, 36 insertions, 1 deletions
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 1504fc976f..e1c9a069ab 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -1714,6 +1714,11 @@ to your Perl administrator.
(W syntax) An illegal character was found in a prototype declaration. Legal
characters in prototypes are $, @, %, *, ;, [, ], &, and \.
+=item Illegal declaration of anonymous subroutine
+
+(F) When using the C<sub> keyword to construct an anonymous subroutine,
+you must always specify a block of code. See L<perlsub>.
+
=item Illegal division by zero
(F) You tried to divide a number by 0. Either something was wrong in
diff --git a/t/op/anonsub.t b/t/op/anonsub.t
index 893a72671c..ddfcd4795d 100755
--- a/t/op/anonsub.t
+++ b/t/op/anonsub.t
@@ -1,5 +1,9 @@
#!./perl
+# Note : we're not using t/test.pl here, because we would need
+# fresh_perl_is, and fresh_perl_is uses a closure -- a special
+# case of what this program tests for.
+
chdir 't' if -d 't';
@INC = '../lib';
$Is_VMS = $^O eq 'VMS';
@@ -12,7 +16,7 @@ $|=1;
undef $/;
@prgs = split "\n########\n", <DATA>;
-print "1..", scalar @prgs, "\n";
+print "1..", 6 + scalar @prgs, "\n";
$tmpfile = "asubtmp000";
1 while -f ++$tmpfile;
@@ -51,6 +55,30 @@ for (@prgs){
print "ok ", ++$i, "\n";
}
+sub test_invalid_decl {
+ my ($code,$todo) = @_;
+ $todo //= '';
+ eval $code;
+ if ($@ =~ /^Illegal declaration of anonymous subroutine at/) {
+ print "ok ", ++$i, " - '$code' is illegal$todo\n";
+ } else {
+ print "not ok ", ++$i, " - '$code' is illegal$todo\n# GOT: $@";
+ }
+}
+
+test_invalid_decl('sub;');
+test_invalid_decl('sub ($) ;');
+test_invalid_decl('{ $x = sub }');
+test_invalid_decl('sub ($) && 1');
+test_invalid_decl('sub ($) : lvalue;',' # TODO');
+
+eval "sub #foo\n{print 1}";
+if ($@ eq '') {
+ print "ok ", ++$i, "\n";
+} else {
+ print "not ok ", ++$i, "\n# GOT: $@";
+}
+
__END__
sub X {
my $n = "ok 1\n";
diff --git a/toke.c b/toke.c
index d95b0a72bb..aff4549138 100644
--- a/toke.c
+++ b/toke.c
@@ -5057,6 +5057,8 @@ Perl_yylex(pTHX)
if (*s == ':' && s[1] != ':')
PL_expect = attrful;
+ else if (!have_name && *s != '{' && key == KEY_sub)
+ Perl_croak(aTHX_ "Illegal declaration of anonymous subroutine");
if (have_proto) {
PL_nextval[PL_nexttoke].opval =