commit 1dd54e3eef7543720eff161457677a35fae2435c Author: Paul Eggert Date: Tue Oct 11 13:06:42 2016 -0700 Work around Samba bug with ':' in symlink contents * src/filelock.c (current_lock_owner): When reading the contents of a lock, treat the UTF-8 for U+F022 as if it were ':' (Bug#24656). diff --git a/src/filelock.c b/src/filelock.c index a2e1df9..d4dfc1d 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -72,8 +72,9 @@ along with GNU Emacs. If not, see . */ /* Normally use a symbolic link to represent a lock. The strategy: to lock a file FN, create a symlink .#FN in FN's - directory, with link data `user@host.pid'. This avoids a single - mount (== failure) point for lock files. + directory, with link data USER@HOST.PID:BOOT. This avoids a single + mount (== failure) point for lock files. The :BOOT is omitted if + the boot time is not available. When the host in the lock data is the current host, we can check if the pid is valid with kill. @@ -102,13 +103,11 @@ along with GNU Emacs. If not, see . */ This is compatible with the locking scheme used by Interleaf (which has contributed this implementation for Emacs), and was designed by - Ethan Jacobson, Kimbo Mundy, and others. - - --karl@cs.umb.edu/karl@hq.ileaf.com. + Karl Berry, Ethan Jacobson, Kimbo Mundy, and others. On some file systems, notably those of MS-Windows, symbolic links - do not work well, so instead of a symlink .#FN -> 'user@host.pid', - the lock is a regular file .#FN with contents 'user@host.pid'. To + do not work well, so instead of a symlink .#FN -> USER@HOST.PID:BOOT, + the lock is a regular file .#FN with contents USER@HOST.PID:BOOT. To establish a lock, a nonce file is created and then renamed to .#FN. On MS-Windows this renaming is atomic unless the lock is forcibly acquired. On other systems the renaming is atomic if the lock is @@ -289,8 +288,8 @@ enum { MAX_LFINFO = 8 * 1024 }; typedef struct { - /* Location of '@', '.', ':' in USER. If there's no colon, COLON - points to the end of USER. */ + /* Location of '@', '.', and ':' (or equivalent) in USER. If there's + no colon or equivalent, COLON points to the end of USER. */ char *at, *dot, *colon; /* Lock file contents USER@HOST.PID with an optional :BOOT_TIME @@ -548,7 +547,7 @@ current_lock_owner (lock_info_type *owner, char *lfname) if (!dot) return -1; - /* The PID is everything from the last `.' to the `:'. */ + /* The PID is everything from the last '.' to the ':' or equivalent. */ if (! c_isdigit (dot[1])) return -1; errno = 0; @@ -556,7 +555,8 @@ current_lock_owner (lock_info_type *owner, char *lfname) if (errno == ERANGE) pid = -1; - /* After the `:', if there is one, comes the boot time. */ + /* After the ':' or equivalent, if there is one, comes the boot time. */ + char *boot = owner->colon + 1; switch (owner->colon[0]) { case 0: @@ -564,10 +564,19 @@ current_lock_owner (lock_info_type *owner, char *lfname) lfinfo_end = owner->colon; break; + case '\357': + /* Treat "\357\200\242" (U+F022 in UTF-8) as if it were ":". + This works around a bug in Samba, which can mistakenly + transliterate ':' to U+F022 in symlink contents (Bug#24656). + See . */ + if (! (boot[0] == '\200' && boot[1] == '\242')) + return -1; + boot += 2; + /* Fall through. */ case ':': - if (! c_isdigit (owner->colon[1])) + if (! c_isdigit (boot[0])) return -1; - boot_time = strtoimax (owner->colon + 1, &lfinfo_end, 10); + boot_time = strtoimax (boot, &lfinfo_end, 10); break; default: