develooper Front page | perl.perl5.porters | Postings from August 2006

Re: [perl #8244] *FILE{IO} does not behave like *FILE for stat()and -X() operators

Thread Previous | Thread Next
From:
Andrew Dougherty
Date:
August 9, 2006 12:15
Subject:
Re: [perl #8244] *FILE{IO} does not behave like *FILE for stat()and -X() operators
Message ID:
Pine.LNX.4.62.0608091448460.14322@fractal.phys.lafayette.edu
On Thu, 27 Jul 2006, Steve Peters via RT wrote:

> On Tue Jan 15 00:10:56 2002, jamie wrote:
> > This is a bug report for perl from jamie@shareable.org,
> > generated with the help of perlbug 1.28 running under perl v5.6.0.
> > 
> > 
> > Although this works fine with functions like `read', `write',
> >    `sysread'
> > etc., it generates an unexpected result with `stat', `lstat' and the
> > `-X' file test operators.
> > 
> > Specifically, when one of these *FILE{IO} references is used in the
> >    file
> > test functions, including `stat' and `lstat', it's converted to a
> >    string
> > (i.e. "IO::Handle=IO(0x12345678)"), and that is used as the file name
> >    to
> > test.
> > 
> > On the other hand, when a typeglob *FILE is used in a file test
> > function, the fstat() system call is used on the open file as
> >    expected.
> > 
> Sorry about not responding to this earlier.  This problem has been fixed
> with change #28628.

Thanks (and sorry to bother the original poster with yet another 
follow-up) but there's a subtle problem (actually discovered by Coverity).
Specifically, in this bit of code (starting around line 2839)
	
	SV* const sv = POPs;
	if (SvTYPE(sv) == SVt_PVGV) {
	    gv = (GV*)sv;
	    goto do_fstat;
	} else if(SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVGV) {
            gv = (GV*)SvRV(sv);
            if (PL_op->op_type == OP_LSTAT)
                goto do_fstat_warning_check;
            goto do_fstat;
        } else if (SvROK(sv) && SvTYPE(SvRV(sv)) == SVt_PVIO) { 
            io = (IO*)SvRV(sv);
            if (PL_op->op_type == OP_LSTAT)
                goto do_fstat_warning_check;
            goto do_fstat_have_io; 
        }

the last clause can end up doing a 'goto do_fstat_warning_check' without
ever setting gv.  That warning check can indeed try to dereference gv.

The following test script (stripped down from t/op/stat.t) illustrates the 
problem.  It currently core dumps at the XXX line while trying to warn 
"lstat() on filehandle %s", GvENAME(gv), and dumps core since gv is NULL.  
I haven't dug deeply enough to decide whether to just beef up the warning 
message (and the corresponding perldiag entry) or whether there's some way 
to make some more useful information available.

    #!./perl
    BEGIN {
	chdir 't' if -d 't';
	@INC = '../lib';
	require './test.pl';	# for which_perl() etc
    }
    use warnings;
    plan tests => 5;
    my $tmpfile = "Op_stat.tmp";
    1 while unlink $tmpfile;

	ok(open(F, ">", $tmpfile), 'can create temp file');
	my @thwap = stat *F{IO};
	ok(@thwap, "stat(*F{IO}) works");    
	ok( -f *F{IO} , "single file tests work with *F{IO}");
	unlink $tmpfile;
	
	ok(open(F, ">", $tmpfile), 'can create second temp file');
	my @thwap2 = lstat *F{IO};  # XXX Note incorrectly using an lstat().
	# Not sure just what to test for here.  These tests are probably
	# not right.  
	ok(@thwap2, "lstat(*F{IO}) works");    # Probably not right

    END {
	1 while unlink $tmpfile;
    }


--
    Andy Dougherty		doughera@lafayette.edu

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