Skip to content

PerlIO.pm name collides with Perl's built-in PerlIO pragma — readParameters()/readSequential() are unreachable by any real plugin #19

Description

@quinnjr

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions