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));

Reply via email to