Skip to content

Commit 9a808ad

Browse files
committed
ParseXS: handle PROTOTYPES keyword more strictly
See the previous commit for a general discussion on the problems with ENABLE/DISABLE-valued keywords. This commit specifically updates how the PROTOTYPES: keyword is handled. Compared with the previous production release, PROTOTYPES is now stricter in validation. It still accepts ENABLE or DISABLE in a case-insensitive matter, but now treats any trailing text as an error, apart from possibly a 'D' or ':'. So Anything apart these forms are compile-time errors now: ENABLE enable Enabled DISABLE; DisablED; etc For backwards compatibility it still treats anything apart from /^ENABLE/ as false; so all except the first example above are treated as DISABLE. But now, it warns if the keyword has been accepted but isn't one of ENABLE/DISABLE.
1 parent 3e449b6 commit 9a808ad

File tree

2 files changed

+132
-22
lines changed

2 files changed

+132
-22
lines changed

dist/ExtUtils-ParseXS/lib/ExtUtils/ParseXS/Node.pm

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3425,14 +3425,21 @@ sub parse {
34253425
my ($keyword) = ($self =~ /(\w+)=/); # final component of class name
34263426

34273427
if ($keyword eq 'PROTOTYPES') {
3428-
# XXX note that for backwards compatibility, parsing the PROTOTYPES
3429-
# keyword's value is very lax: it is case insensitive, and ignores
3430-
# any trailing garbage on the line
3431-
unless ($s =~ /^(ENABLE|DISABLE)\b/i) {
3432-
my ($keyword) = ($self =~ /(\w+)=/); # final component of class name
3428+
# For backwards compatibility, parsing the PROTOTYPES
3429+
# keyword's value is very lax: in particular, anything that
3430+
# didn't match 'ENABLE' (such as 'Enabled' or 'ENABLED') used to
3431+
# be treated as valid but false. Continue to use this
3432+
# interpretation for backcomp, but warn.
3433+
3434+
unless ($s =~ /^ ((ENABLE|DISABLE) D? ;?) \s* $ /xi) {
34333435
$pxs->death("Error: $keyword: ENABLE/DISABLE")
34343436
}
3435-
$self->{enable} = uc($1) eq 'ENABLE' ? 1 : 0;
3437+
my ($value, $en_dis) = ($1, $2);
3438+
$self->{enable} = $en_dis eq 'ENABLE' ? 1 : 0;
3439+
unless ($value =~ /^(ENABLE|DISABLE)$/) {
3440+
$pxs->Warn("Warning: invalid PROTOTYPES value '$value' interpreted as "
3441+
. ($self->{enable} ? 'ENABLE' : 'DISABLE'));
3442+
}
34363443
}
34373444
else {
34383445
# SCOPE / VERSIONCHECK / EXPORT_XSUB_SYMBOLS

dist/ExtUtils-ParseXS/t/001-basic.t

Lines changed: 119 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4307,21 +4307,6 @@ EOF
43074307
[ 1, 0, qr{Error: VERSIONCHECK: ENABLE/DISABLE}, "should die" ],
43084308
],
43094309
4310-
[
4311-
"PROTOTYPES: long word",
4312-
[ Q(<<'EOF') ],
4313-
|PROTOTYPES: ENABLEblah
4314-
EOF
4315-
[ 1, 0, qr{Error: PROTOTYPES: ENABLE/DISABLE}, "should die" ],
4316-
],
4317-
[
4318-
"PROTOTYPES: trailing text (stupid but legal)",
4319-
[ Q(<<'EOF') ],
4320-
|PROTOTYPES: diSAble blah # bloo +$%
4321-
EOF
4322-
[ 0, 0, qr{dXSARGS}, "boot fn generated" ],
4323-
],
4324-
43254310
[
43264311
"EXPORT_XSUB_SYMBOLS: long word",
43274312
[ Q(<<'EOF') ],
@@ -4370,7 +4355,125 @@ EOF
43704355
43714356
43724357
{
4373-
# Test per-XSUB ENABLE/DISABLE keywords
4358+
# Test PROTOTYPES keyword. Note that there is a lot of
4359+
# backwards-compatibility oddness in the keyword's value
4360+
4361+
my $preamble = Q(<<'EOF');
4362+
|MODULE = Foo PACKAGE = Foo
4363+
|
4364+
EOF
4365+
4366+
my @test_fns = (
4367+
[
4368+
"PROTOTYPES: ENABLE",
4369+
[ Q(<<'EOF') ],
4370+
|PROTOTYPES: ENABLE
4371+
|
4372+
|void
4373+
|foo(int a, int b)
4374+
EOF
4375+
[ 0, 0, qr{newXSproto_portable.*"\$\$"}, "has proto" ],
4376+
],
4377+
[
4378+
"PROTOTYPES: ENABLED",
4379+
[ Q(<<'EOF') ],
4380+
|PROTOTYPES: ENABLED
4381+
|
4382+
|void
4383+
|foo(int a, int b)
4384+
EOF
4385+
[ 0, 0, qr{newXSproto_portable.*"\$\$"}, "has proto" ],
4386+
[ 1, 0, qr{Warning: invalid PROTOTYPES value 'ENABLED' interpreted as ENABLE},
4387+
"got warning" ],
4388+
],
4389+
[
4390+
"PROTOTYPES: ENABLE;",
4391+
[ Q(<<'EOF') ],
4392+
|PROTOTYPES: ENABLE;
4393+
|
4394+
|void
4395+
|foo(int a, int b)
4396+
EOF
4397+
[ 0, 0, qr{newXSproto_portable.*"\$\$"}, "has proto" ],
4398+
[ 1, 0, qr{Warning: invalid PROTOTYPES value 'ENABLE;' interpreted as ENABLE},
4399+
"got warning" ],
4400+
],
4401+
4402+
[
4403+
"PROTOTYPES: DISABLE",
4404+
[ Q(<<'EOF') ],
4405+
|PROTOTYPES: DISABLE
4406+
|
4407+
|void
4408+
|foo(int a, int b)
4409+
EOF
4410+
[ 0, 1, qr{"\$\$"}, "doesn't have proto" ],
4411+
],
4412+
[
4413+
"PROTOTYPES: DISABLED",
4414+
[ Q(<<'EOF') ],
4415+
|PROTOTYPES: DISABLED
4416+
|
4417+
|void
4418+
|foo(int a, int b)
4419+
EOF
4420+
[ 0, 1, qr{"\$\$"}, "doesn't have proto" ],
4421+
[ 1, 0, qr{Warning: invalid PROTOTYPES value 'DISABLED' interpreted as DISABLE},
4422+
"got warning" ],
4423+
],
4424+
[
4425+
"PROTOTYPES: DISABLE;",
4426+
[ Q(<<'EOF') ],
4427+
|PROTOTYPES: DISABLE;
4428+
|
4429+
|void
4430+
|foo(int a, int b)
4431+
EOF
4432+
[ 0, 1, qr{"\$\$"}, "doesn't have proto" ],
4433+
[ 1, 0, qr{Warning: invalid PROTOTYPES value 'DISABLE;' interpreted as DISABLE},
4434+
"got warning" ],
4435+
],
4436+
4437+
[
4438+
"PROTOTYPES: long word",
4439+
[ Q(<<'EOF') ],
4440+
|PROTOTYPES: ENABLEblah
4441+
|
4442+
|void
4443+
|foo(int a, int b)
4444+
EOF
4445+
[ 1, 0, qr{Error: PROTOTYPES: ENABLE/DISABLE}, "should die" ],
4446+
],
4447+
[
4448+
"PROTOTYPES: trailing text",
4449+
[ Q(<<'EOF') ],
4450+
|PROTOTYPES: ENABLE blah
4451+
|
4452+
|void
4453+
|foo(int a, int b)
4454+
EOF
4455+
[ 1, 0, qr{Error: PROTOTYPES: ENABLE/DISABLE}, "should die" ],
4456+
],
4457+
[
4458+
"PROTOTYPES: trailing text and comment)",
4459+
[ Q(<<'EOF') ],
4460+
|PROTOTYPES: DISABLE blah # bloo +$%
4461+
|
4462+
|void
4463+
|foo(int a, int b)
4464+
EOF
4465+
[ 1, 0, qr{Error: PROTOTYPES: ENABLE/DISABLE}, "should die" ],
4466+
],
4467+
4468+
4469+
);
4470+
4471+
test_many($preamble, 'boot_Foo', \@test_fns);
4472+
}
4473+
4474+
4475+
{
4476+
# Test per-XSUB ENABLE/DISABLE keywords except PROTOTYPES
43744477

43754478
my $preamble = Q(<<'EOF');
43764479
|MODULE = Foo PACKAGE = Foo

0 commit comments

Comments
 (0)