Skip Menu |

This queue is for tickets about the File-Slurp CPAN distribution.

Report information
The Basics
Id: 24302
Status: resolved
Priority: 0/
Queue: File-Slurp

People
Owner: Nobody in particular
Requestors: SAPER [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 9999.11
Fixed in: (no value)



Subject: File::Slurp doesn't play well with Path::Class (and objects in general)
Hello, I was again hit by the following problem: $ perl -MPath::Class -MFile::Slurp -e'print read_file(file(shift))' whatever Can't locate object method "IO" via package "B::HV" at /usr/lib/perl5/site_perl/5.8.7/File/Slurp.pm line 116. Previously, I worked around this error using crufty and unspeakable methods, but this time investigated a little in order to find its root. The problem lies at line 88 of File/Slurp.pm (version 9999.12): if ( ref $file_name ) { ... This test is wrong because you're only testing if $file_name is a reference, while you should check if it's actually a handle. I see two solutions. The first is to use Scalar::Util::reftype(): if (reftype($file_name) eq 'GLOB') { ... but Scalar::Util is not available on old Perls. The second solution is to use UNIVERSAL::isa(): if (UNIVERSAL::isa($file_name, 'GLOB') { ... which works on any Perl. And in order to please chromatic, you can either add UNIVERSAL::isa as a File::Slurp dependency or conditionally use it: BEGIN { eval 'use UNIVERSAL::isa' } Regards -- Close the world, txEn eht nepO.
From: SAPER [...] cpan.org
Here is a patch that fixes this problem and adds a test script for this bug. -- Close the world, txEn eht nepO.
diff -ruN File-Slurp-9999.12-orig/lib/File/Slurp.pm File-Slurp-9999.12/lib/File/Slurp.pm --- File-Slurp-9999.12-orig/lib/File/Slurp.pm 2006-02-17 07:13:51.000000000 +0100 +++ File-Slurp-9999.12/lib/File/Slurp.pm 2007-06-08 16:21:06.858317759 +0200 @@ -6,6 +6,7 @@ use POSIX qw( :fcntl_h ) ; use Fcntl qw( :DEFAULT ) ; use Symbol ; +BEGIN { eval 'use UNIVERSAL::isa' } my $is_win32 = $^O =~ /win32/i ; @@ -85,7 +86,7 @@ # check if we are reading from a handle (glob ref or IO:: object) - if ( ref $file_name ) { + if ( ref $file_name && (UNIVERSAL::isa($file_name, 'GLOB') || UNIVERSAL::isa($file_name, 'IO')) ) { # slurping a handle so use it and don't open anything. # set the block size so we know it is a handle and read that amount diff -ruN File-Slurp-9999.12-orig/t/file_object.t File-Slurp-9999.12/t/file_object.t --- File-Slurp-9999.12-orig/t/file_object.t 1970-01-01 01:00:00.000000000 +0100 +++ File-Slurp-9999.12/t/file_object.t 2007-06-08 16:16:43.644607504 +0200 @@ -0,0 +1,45 @@ +#!perl -T +use strict; +use Test::More; +use File::Slurp; +use Scalar::Util qw(tainted); + +plan tests => 4; + +my $path = "data.txt"; +my $data = "random junk\n"; + +# create an object +my $obj = FileObject->new($path); +isa_ok( $obj, 'FileObject' ); +is( "$obj", $path, "check that the object correctly stringifies" ); + +SKIP: { + # write something to that file + open(FILE, ">$path") or skip 4, "can't write to '$path': $!"; + print FILE $data; + close(FILE); + + # pass it to read_file() + my $content = eval { read_file($obj) }; + is( $@, '', "passing an object to read_file()" ); + is( $content, $data, "checking that the content matches the data" ); +} + +unlink $path; + + +# the following mimics the parts from Path::Class causing +# problems with File::Slurp +package FileObject; +use overload + q[""] => \&stringify, fallback => 1; + +sub new { + return bless { path => $_[1] }, $_[0] +} + +sub stringify { + return $_[0]->{path} +} + diff -ruN File-Slurp-9999.12-orig/t/taint.t File-Slurp-9999.12/t/taint.t --- File-Slurp-9999.12-orig/t/taint.t 1970-01-01 01:00:00.000000000 +0100 +++ File-Slurp-9999.12/t/taint.t 2007-06-08 16:15:42.852350224 +0200 @@ -0,0 +1,30 @@ +#!perl -T +use strict; +use Test::More; +use File::Slurp; +use Scalar::Util qw(tainted); + +plan tests => 4; + +my $path = "data.txt"; +my $data = "random junk\n"; + +SKIP: { + # write something to that file + open(FILE, ">$path") or skip 4, "can't write to '$path': $!"; + print FILE $data; + close(FILE); + + # read the file using File::Slurp in scalar context + my $content = eval { read_file($path) }; + is( $@, '', "read_file() in scalar context" ); + ok( tainted($content), " => returned content should be tainted" ); + + # read the file using File::Slurp in list context + my @content = eval { read_file($path) }; + is( $@, '', "read_file() in list context" ); + ok( tainted($content[0]), " => returned content should be tainted" ); +} + +unlink $path; +
On Fri Jun 08 10:28:00 2007, SAPER wrote: Show quoted text
> Here is a patch that fixes this problem and adds a test script > for this bug.
Hi there. I tried the patch specified but received the following error: read_file 'SCALAR(0x194dee0)' - sysopen: No such file or directory at -e line 1 for this code: perl -MFile::Slurp=read_file -e 'my $file = "/bin/ls"; my $stuff = read_file(\$file)' As far as I understand, the code should behave when given a reference as the first argument--at least providing an error message of its own rather than dying with a stringified ref error. Not sure what the proper way to fix it is yet, though.
On Fri Jun 08 10:28:00 2007, SAPER wrote: Show quoted text
> Here is a patch that fixes this problem and adds a test script > for this bug.
I saw this problem when I tried to do slurp(MyApp->path_to("root/foo")) in a Catalyst controller. This patch fixes the issue.
Subject: Re: [rt.cpan.org #24302] File::Slurp doesn't play well with Path::Class (and objects in general)
Date: Thu, 22 Apr 2010 02:21:18 -0400
To: bug-File-Slurp [...] rt.cpan.org
From: "Uri Guttman" <uri [...] StemSystems.com>
Show quoted text
>>>>> "CNvR" == Christopher Nehren via RT <bug-File-Slurp@rt.cpan.org> writes:
Show quoted text
CNvR> Queue: File-Slurp CNvR> Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=24302 >
Show quoted text
CNvR> On Fri Jun 08 10:28:00 2007, SAPER wrote:
Show quoted text
>> Here is a patch that fixes this problem and adds a test script >> for this bug.
Show quoted text
CNvR> Hi there. I tried the patch specified but received the following error:
Show quoted text
CNvR> read_file 'SCALAR(0x194dee0)' - sysopen: No such file or directory at -e CNvR> line 1
Show quoted text
CNvR> for this code:
Show quoted text
CNvR> perl -MFile::Slurp=read_file -e 'my $file = "/bin/ls"; my $stuff = CNvR> read_file(\$file)'
Show quoted text
CNvR> As far as I understand, the code should behave when given a CNvR> reference as the first argument--at least providing an error CNvR> message of its own rather than dying with a stringified ref CNvR> error. Not sure what the proper way to fix it is yet, though.
you are in error here. you are passing a ref to a scalar which is not legal for file::slurp. so the current code (without the object patch) also barfs with this error: Can't locate object method "IO" via package "B::PV" at ../lib/File/Slurp.pm line 146. because this code is being passed a scalar ref and the svref_2object call fails. i can trap this in an eval and maybe spit out a better error message. B::svref_2object( $read_fh )->IO->IoFLAGS & 16 i am working on releasing a new version but this feature may not get in as i need to understand it better. thanx, uri -- Uri Guttman ------ uri@stemsystems.com -------- http://www.sysarch.com -- ----- Perl Code Review , Architecture, Development, Training, Support ------ --------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------