[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [groff] [PATCH] Avoid Perl's unsafe "<>" operator

From: Ralph Corderoy
Subject: Re: [groff] [PATCH] Avoid Perl's unsafe "<>" operator
Date: Sun, 03 Mar 2019 13:21:49 +0000

Hi Colin,

> Perl's "open" documentation even notes for the "< $file\0" trick that
> "this may not work on some bizarre filesystems", which suggests to me
> that such a robust proof isn't possible.

No, that's a misquote.

        $file =~ s#^(\s)#./$1#;
        open(my $fh, "< $file\0")
            || die "Can't open $file: $!";

    (this may not work on some bizarre filesystems).

The `bizarre' bit is referring to non-POSIX filesystems that don't like
`./' as a prefix for the current directory.

If this wasn't sufficient then the prominent ARGV::readonly solution
would be buggy.  As for `-', `<-\0' works.

    $ cat ' '
    one space
    one ends
    $ cat '  '
    two spaces
    two ends
    $ echo stdin | 
    > perl -e '
    >       @ARGV = map { s,^\s,./$&,; "<$_\0" } @ARGV;
    >       while (<>) {chomp; print ":$_:\n"}
    >   ' ' ' - 'date|' '|touch foo' '  '
    :one space:
    :one ends:
    Can't open <date|: No such file or directory at -e line 3, <> line 3.
    Can't open <|touch foo: No such file or directory at -e line 3, <> line 3.
    :two spaces:
    :two ends:
    $ ls foo
    ls: cannot access 'foo': No such file or directory

> we're trying to come up with ways to add extra characters to its input
> that suppress that magic.

We're using the method described in documentation written by Tom
Christiansen and his pedigree says to me that's sufficient.  I agree in
general one looks for a certain way to be safe, but this seems the
accepted Perl idiom.

Google shamefully ruined the DejaNews legacy they inherited, otherwise I
could find a better discussion.

    If magic `open' is a bit too magical for you, you don't have to turn
    to `sysopen'.  To open a file with arbitrary weird characters in it,
    it's necessary to protect any leading and trailing whitespace.
    Leading whitespace is protected by inserting a `"./"' in front of a
    filename that starts with whitespace.  Trailing whitespace is
    protected by appending an ASCII NUL byte (`"\0"') at the end off the

        $file =~ s#^(\s)#./$1#;
        open(FH, "< $file\0")   || die "can't open $file: $!";

    This assumes, of course, that your system considers dot the current
    working directory, slash the directory separator, and disallows
    ASCII NULs within a valid filename.  Most systems follow these
    conventions, including all POSIX systems as well as proprietary
    Microsoft systems.  The only vaguely popular system that doesn't
    work this way is the proprietary Macintosh system, which uses a
    colon where the rest of us use a slash.  Maybe `sysopen' isn't such
    a bad idea after all.

I think we can ignore the dirty old Mac brigade.  :-)

Cheers, Ralph.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]