From 40c426a150c5d885d8a2509358831c9bb1e1c6ad Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Wed, 12 Oct 2016 09:01:03 -0700 Subject: [PATCH] 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). Backport from master. --- src/filelock.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/filelock.c b/src/filelock.c index 8aaa656438d..23bb4b83bd5 100644 --- a/src/filelock.c +++ b/src/filelock.c @@ -71,8 +71,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. @@ -101,13 +102,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 @@ -298,8 +297,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 @@ -557,7 +556,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; @@ -565,7 +564,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: @@ -573,10 +573,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: -- 2.39.2