| Summary: | Open() fails if filename ends in a space | ||
|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | GeoffLeach <geoffleach.gl> |
| Component: | perl | Assignee: | Jitka Plesnikova <jplesnik> |
| Status: | CLOSED NOTABUG | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
| Severity: | low | Docs Contact: | |
| Priority: | unspecified | ||
| Version: | 23 | CC: | cweyl, iarnell, jplesnik, kasal, perl-devel, ppisar, psabata, rc040203, tcallawa |
| Target Milestone: | --- | ||
| Target Release: | --- | ||
| Hardware: | i686 | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2016-08-30 15:00:10 UTC | Type: | Bug |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
|
Description
GeoffLeach
2016-08-17 20:41:56 UTC
Checking what the code does on operating level shows:
$ strace -e open ./test
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libperl.so.5.22", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libresolv.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libnsl.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libm.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libcrypt.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libutil.so.1", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/lib64/libfreebl3.so", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/dev/urandom", O_RDONLY) = 3
open("./test", O_RDONLY) = 3
open("/usr/share/perl5/strict.pm", O_RDONLY) = 4
open("/usr/share/perl5/warnings.pm", O_RDONLY) = 4
open("t", O_RDONLY) = -1 ENOENT (No such file or directory)
whoops: No such file or directory at ./test line 5.
+++ exited with 2 +++
So the problem is that the trailing white space is removed.
Reading open() documentation in perlfunc POD revelads this is a feature:
The filename passed to the one- and two-argument forms of open()
will have leading and trailing whitespace deleted and normal
redirection characters honored. This property, known as "magic
open", can often be used to good effect. A user could specify a
filename of "rsh cat file |", or you could change certain
filenames as needed:
$filename =~ s/(.*\.gz)\s*$/gzip -dc < $1|/;
open(FH, $filename) or die "Can't open $filename: $!";
Use the three-argument form to open a file with arbitrary weird
characters in it,
open(FOO, "<", $file)
|| die "can't open < $file: $!";
otherwise it's necessary to protect any leading and trailing
whitespace:
$file =~ s#^(\s)#./$1#;
open(FOO, "< $file\0")
|| die "open failed: $!";
Therefore I recommend you to use 3-argument form with explicit open mode like this:
$o = open($fh, '<', $file)|| die 'whoops';
|