Summary
PerlIO.pm (repo root) defines readParameters($$) and readSequential($$), intended to be called as PerlIO::readParameters(...) / PerlIO::readSequential(...) from Perl plugins (e.g. plugins/GreenGenes/GreenGenesPlugin.pl, plugins/DEMIC, plugins/WGEval, plugins/PRINSEQ).
The problem: PerlIO is also the name of a built-in Perl core pragma (the I/O layers subsystem — perldoc PerlIO). When a plugin does:
use lib '.';
use PerlIO;
...
%params = PerlIO::readParameters($_[0]);
use PerlIO; resolves to Perl's own built-in PerlIO module/pragma instead of the project's PerlIO.pm, even with use lib '.' prepending the current directory to @INC. The use statement succeeds silently (no "Can't locate" error), but PerlIO::readParameters doesn't exist on the built-in module, so any real call fails at runtime with:
Undefined subroutine &PerlIO::readParameters called at .../GreenGenesPlugin.pl line N.
This means readParameters()/readSequential() have likely never been reachable by any plugin that follows the documented use lib '.'; use PerlIO; pattern, since the name collision predates any change I'm aware of.
Reproduction
# minimal repro, run from repo root
use lib '.';
use PerlIO;
print PerlIO::readParameters("/dev/null");
Undefined subroutine &main::readParameters called at PerlIO.pm line 1.
(exact error text varies depending on whether PerlIO.pm itself is missing a package declaration — see related bugs below — but in all variants the plugin-facing call to PerlIO::readParameters fails.)
Related bugs in the same file (already fixed downstream, see #18)
While investigating this, three other independent bugs were found and fixed in PerlIO.pm in #18:
open(<DATA>, $inputfile) — invalid two-argument open syntax using the diamond operator as a filehandle; when "fixed" naively to open(DATA, $inputfile) this becomes a two-arg open, which is a shell-injection vector for a crafted $inputfile (needs the safe 3-arg open(DATA, '<', $inputfile) form).
my $inputfile = @_; — scalar-context array assignment, evaluates to the argument count, not the first argument.
return($retval); in readParameters — wrong sigil; %retval is the populated hash, but a different, never-assigned scalar $retval is returned instead, so the function always returned nothing even when otherwise reachable.
- Missing trailing
1; — Perl modules must return a true value; without it, any successful use/require of PerlIO.pm fails with "PerlIO.pm did not return a true value".
None of those four fixes matter in practice until this naming collision is resolved, since the module is currently unreachable under its own name.
Suggested fix
Rename the module to something that doesn't collide with a core Perl module — e.g. PluMAIO.pm or PerlPluMAIO.pm (mirroring the existing PyIO.py/RIO.R naming, perhaps PerlIOUtils.pm) — and update every plugin's use PerlIO; / PerlIO::readParameters call site accordingly. This is a breaking rename for any downstream plugin already written against the current (currently-nonfunctional) name, so flagging for a maintainer decision rather than making the call unilaterally.
Environment
Found while working on #18 (verified against Perl 5.42, but the collision is a Perl core-module-naming issue, not version-specific — same collision exists on any Perl 5.x with the PerlIO layers subsystem, i.e. all supported versions).
Summary
PerlIO.pm(repo root) definesreadParameters($$)andreadSequential($$), intended to be called asPerlIO::readParameters(...)/PerlIO::readSequential(...)from Perl plugins (e.g.plugins/GreenGenes/GreenGenesPlugin.pl,plugins/DEMIC,plugins/WGEval,plugins/PRINSEQ).The problem:
PerlIOis also the name of a built-in Perl core pragma (the I/O layers subsystem —perldoc PerlIO). When a plugin does:use PerlIO;resolves to Perl's own built-inPerlIOmodule/pragma instead of the project'sPerlIO.pm, even withuse lib '.'prepending the current directory to@INC. Theusestatement succeeds silently (no "Can't locate" error), butPerlIO::readParametersdoesn't exist on the built-in module, so any real call fails at runtime with:This means
readParameters()/readSequential()have likely never been reachable by any plugin that follows the documenteduse lib '.'; use PerlIO;pattern, since the name collision predates any change I'm aware of.Reproduction
(exact error text varies depending on whether
PerlIO.pmitself is missing a package declaration — see related bugs below — but in all variants the plugin-facing call toPerlIO::readParametersfails.)Related bugs in the same file (already fixed downstream, see #18)
While investigating this, three other independent bugs were found and fixed in
PerlIO.pmin #18:open(<DATA>, $inputfile)— invalid two-argumentopensyntax using the diamond operator as a filehandle; when "fixed" naively toopen(DATA, $inputfile)this becomes a two-arg open, which is a shell-injection vector for a crafted$inputfile(needs the safe 3-argopen(DATA, '<', $inputfile)form).my $inputfile = @_;— scalar-context array assignment, evaluates to the argument count, not the first argument.return($retval);inreadParameters— wrong sigil;%retvalis the populated hash, but a different, never-assigned scalar$retvalis returned instead, so the function always returned nothing even when otherwise reachable.1;— Perl modules must return a true value; without it, any successfuluse/requireofPerlIO.pmfails with "PerlIO.pm did not return a true value".None of those four fixes matter in practice until this naming collision is resolved, since the module is currently unreachable under its own name.
Suggested fix
Rename the module to something that doesn't collide with a core Perl module — e.g.
PluMAIO.pmorPerlPluMAIO.pm(mirroring the existingPyIO.py/RIO.Rnaming, perhapsPerlIOUtils.pm) — and update every plugin'suse PerlIO;/PerlIO::readParameterscall site accordingly. This is a breaking rename for any downstream plugin already written against the current (currently-nonfunctional) name, so flagging for a maintainer decision rather than making the call unilaterally.Environment
Found while working on #18 (verified against Perl 5.42, but the collision is a Perl core-module-naming issue, not version-specific — same collision exists on any Perl 5.x with the
PerlIOlayers subsystem, i.e. all supported versions).