Skip to content
Draft
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
10 changes: 8 additions & 2 deletions Expat/Expat.xs
Original file line number Diff line number Diff line change
Expand Up @@ -2353,12 +2353,18 @@ XML_Do_External_Parse(parser, result)
}
else if (SvROK(result) && isGV(SvRV(result))) {
/* Lexical filehandle (open my $fh) - a reference to a glob */
IO *io = GvIOp((GV*)SvRV(result));
if (!io)
croak("ExternEnt handler returned an unopened filehandle");
RETVAL = parse_stream(parser,
sv_2mortal(newRV_inc((SV*) GvIOp((GV*)SvRV(result)))));
sv_2mortal(newRV_inc((SV*) io)));
}
else if (isGV(result)) {
IO *io = GvIOp(result);
if (!io)
croak("ExternEnt handler returned an unopened filehandle");
RETVAL = parse_stream(parser,
sv_2mortal(newRV_inc((SV*) GvIOp(result))));
sv_2mortal(newRV_inc((SV*) io)));
}
else if (SvPOK(result)) {
STRLEN eslen;
Expand Down
32 changes: 31 additions & 1 deletion t/extern_ent_lexical_glob.t
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use File::Temp qw(tempfile);
if ($] < 5.012) {
plan skip_all => 'Lexical filehandles lack read() method before Perl 5.12';
}
plan tests => 2;
plan tests => 4;

# Create a temporary entity file
my ($fh, $entfile) = tempfile(UNLINK => 1, SUFFIX => '.ent');
Expand Down Expand Up @@ -46,3 +46,33 @@ XML
is($@, '', 'parsing with lexical glob ExternEnt handler does not die');
is($chardata, 'hello world', 'character data from lexical glob entity is correct');
}

# Test 3: unopened lexical glob croaks instead of segfaulting
{
my $p = XML::Parser->new(
Handlers => {
ExternEnt => sub {
my $fh; # declared but never opened
return \$fh; # returns reference to undef scalar, not a glob
},
},
);

eval { $p->parse($xml) };
ok($@, 'unopened lexical scalar ref dies gracefully');
}

# Test 4: unopened bare glob croaks instead of segfaulting
{
no warnings 'once';
my $p = XML::Parser->new(
Handlers => {
ExternEnt => sub {
return *UNOPENED_TEST_GLOB; # glob with no IO slot
},
},
);

eval { $p->parse($xml) };
like($@, qr/unopened filehandle/i, 'bare unopened glob gives useful error');
}
Loading