Package: libtag1
Version: 1.3.1-1
Severity: normal
Tags: patch
When opening a file, taglib uses the access() system call to determine
whether a file is writable. It uses this information to decide whether
to open it in read-write or read-only mode. access() is not a reliable
means of determining the true accessability of a file. It is better to
just try opening the file. Basically: don't ask for permission first,
just do it, and the system will tell you if you can't.
The following alternate way of doing it is better. Moreover, it is
cheaper (the original method always costs two system calls, this
method can cost 2 system calls but might cost only 1).
This bug manisfested itself to me when opening files with read only
modes over an sshfs mount. sshfs does not implement the access()
system call so fuse converts it into a no-op that always returns
true. taglib then thinks it can open the file for writing, and
tries and fails to do so and gives up. If it had tried, it could have
opened the file for reading.
-Phil
-- System Information:
Debian Release: 3.1
Architecture: i386 (i686)
Kernel: Linux 2.6.8-2-686
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Versions of packages libtag1 depends on:
ii libc6 2.3.2.ds1-22sarge4 GNU C Library: Shared libraries an
ii libgcc1 1:3.4.3-13sarge1 GCC support library
ii libstdc++5 1:3.3.5-13 The GNU Standard C++ Library v3
ii zlib1g 1:1.2.2-4.sarge.2 compression library - runtime
-- no debconf information
--- taglib-1.3.1/taglib/toolkit/tfile.cpp 2006/12/19 17:05:58 1.1
+++ taglib-1.3.1/taglib/toolkit/tfile.cpp 2006/12/19 17:07:49
@@ -59,8 +59,12 @@
{
d = new FilePrivate(::strdup(file));
- d->readOnly = !isWritable(file);
- d->file = fopen(file, d->readOnly ? "r" : "r+");
+ d->readOnly = 0;
+ d->file = fopen(file, "r+");
+ if (!d->file) {
+ d->readOnly = 1;
+ d->file = fopen(file, "r");
+ }
if(!d->file)
debug("Could not open file " + String(file));