develooper Front page | perl.perl5.porters | Postings from October 2011

[perl #96116] File::Glob ':glob' causes infinite loop

Thread Previous | Thread Next
From:
Father Chrysostomos via RT
Date:
October 26, 2011 08:46
Subject:
[perl #96116] File::Glob ':glob' causes infinite loop
Message ID:
rt-3.6.HEAD-31297-1319644000-1649.96116-15-0@perl.org
On Wed Oct 26 05:20:00 2011, jpl@research.att.com wrote:
> There are (at least:-) ) two problems here.  One is that the synopsis says
> 
>     SYNOPSIS
>               use File::Glob ':glob';
> 
> But tag ":glob" includes tag 'glob', which can lead to infinite looping 
> behavior when used in scalar context, like
> 
> while (<*.c>) { ... }
> 
> That makes tag 'glob' very dangerous, so it should not be invoked by 
> default.  It is possible, though unlikely, that someone is depending on
> 
>     $lastfile = <*.c>;
> 
> to return the last matching file name (which it does), so we cannot 
> simply drop the 'glob' tag from ':glob'.  We need a new, safe tag 
> (':safeglob'??) to advertise in the synopsis.
> 
> The other problem is getting glob to recognize blanks in file names, 
> which is what the OP was trying to do with
> 
>     use File::Glob ':glob';
> 
> in the first place, since, by default, blanks separate distinct 
> patterns.  It's a one or two line change to Glob.pm to have it recognize 
> an array reference, and turn it into an array of patterns.  This works 
> just fine and cannot break any plausible existing code.  Unfortunately, 
> it only works when glob is invoked directly, not via angle-brackets.
> 
>     while (my $file = glob(['*.c', '*.h', 'em bedded*.txt']));   # works
>     while (my $file = <['*.c', '*.h', 'em bedded*.txt']>);   # doesn't
> 
> I lack the smarts to fix this, and having glob() work but <> not work is 
> not acceptable.

I think that is acceptable, as <> is a quote-like operator.  See my
response at
<http://www.nntp.perl.org/group/perl.perl5.porters/2011/10/msg178117.html>.

I’ve already started working through the pile of bugs I described there.

But as for glob([...]), I think a pragma (or import option) and a plain
list would be better, precisely to avoid the problem of how to deal with
overloaded array references, etc.  (Almost every piece of code that does
different things depending on the type of the operand has unfixable bugs
in it.)

Since people already know that bsd_glob() does not split on spaces, we
could have ‘use File::Glob ':bsd_glob'’ export a special glob() function
that maintains state but calls bsd_glob underneath.

I can think of several other interfaces, but this is the one I prefer. 
The problem with a pragma is that :case and :nocase are global, not
lexical.  But a :split/:nosplit option would have to be lexical to avoid
breakage.  Then confusion ensues.


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About