Skip Menu |
 

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

Report information
The Basics
Id: 84918
Status: open
Priority: 0/
Queue: File-Slurp

People
Owner: Nobody in particular
Requestors: corion [...] corion.net
Cc:
AdminCc:

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



Subject: read_file() ignores binmode option for short files
Date: Mon, 29 Apr 2013 21:50:18 +0200
To: bug-File-Slurp [...] rt.cpan.org
From: Max Maischein <corion [...] corion.net>
Download (untitled) / with headers
text/plain 762b
Hello, thanks for writing File::Slurp. I noticed a bug in File::Slurp which leads to bad data being read. The binmode option is ignored in the code path for short files. Especially when reading and writing text files on Windows using {binmode => ':raw'}, but also when processing UTF-8 files, this is quite bad. The quick workaround is to simply delete that wrong optimization at the start of read_file(). If you want to keep the code path for short files, you will have to come up with your own way of reimplementing IO layers, or at least detect :raw and likely :utf-8 layers and act on them appropriately. Especially the line to "fix" Windows input does not seem prudent: $buf =~ s/\015\012/\n/g if $is_win32 ; Thanks for looking at this, -max
Download (untitled) / with headers
text/plain 714b
Show quoted text
> I noticed a bug in File::Slurp which leads to bad data being read. The > binmode option is ignored in the code path for short files. Especially > when reading and writing text files on Windows using {binmode => > ':raw'}, but also when processing UTF-8 files, this is quite bad.
Reviewing this bug, the problem is not in the short path, but in the long path, which does not cope with read_file( 'file.txt', { binmode => ':crlf' }); or read_file( 'file.txt', { binmode => ':encoding(Latin-1)' }); on Windows, due to the hand-rolled "fixup" of newlines under the assumption that all binmode arguments need to trigger this. I've attached a test file for this. The tests fail under Windows currently.
Subject: newline_binmode.t
Download newline_binmode.t
text/x-perl 1.3k
use strict; use warnings; use IO::Handle (); use File::Basename (); use File::Spec (); use lib File::Spec->catdir(File::Spec->rel2abs(File::Basename::dirname(__FILE__)), 'lib'); use FileSlurpTest qw(temp_file_path); use File::Slurp qw(read_file write_file); use Test::More; plan tests => 6; my $binmode; for (':encoding(Latin-1)', ':crlf', ':raw') { $binmode = $_; my $data = "\n\n\n"; my $file_name = temp_file_path(); stdio_write_file($file_name, $data); my $slurped_data = read_file($file_name, { binmode => $binmode }); my $stdio_slurped_data = stdio_read_file( $file_name ) ; print 'data ', unpack( 'H*', $data), "\n", 'slurp ', unpack('H*', $slurped_data), "\n", 'stdio slurp ', unpack('H*', $stdio_slurped_data), "\n"; is($data, $slurped_data, "slurp ($binmode)"); write_file($file_name, { binmode => $binmode }, $data ); $slurped_data = stdio_read_file($file_name); is($data, $slurped_data, "spew ($binmode)"); unlink $file_name; }; sub stdio_write_file { my ($file_name, $data) = @_; open (my $fh, '>', $file_name) || die "Couldn't create $file_name: $!"; binmode $fh, $binmode; $fh->print($data); } sub stdio_read_file { my ($file_name) = @_; open (my $fh, '<', $file_name ) || die "Couldn't open $file_name: $!"; binmode $fh, $binmode; local $/; my $data = <$fh>; return $data; }


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

Please report any issues with rt.cpan.org to rt-cpan-admin@bestpractical.com.