fs/adfs: fix filename fixup handling for "/" and "//" names
authorRussell King <rmk+kernel@armlinux.org.uk>
Sun, 24 Mar 2019 14:00:35 +0000 (14:00 +0000)
committerRussell King <rmk+kernel@armlinux.org.uk>
Fri, 31 May 2019 09:31:07 +0000 (10:31 +0100)
Avoid translating "/" and "//" directory entry names to the special
"." and ".." names by instead converting the first character to "^".

Acked-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
fs/adfs/dir.c

index 51ed80ff10a542054774ad08b0891356e338c799..fe39310c1a0abe90bd5c2b0f3040b9089d939dc2 100644 (file)
@@ -18,18 +18,25 @@ static DEFINE_RWLOCK(adfs_dir_lock);
 
 void adfs_object_fixup(struct adfs_dir *dir, struct object_info *obj)
 {
-       unsigned int i;
+       unsigned int dots, i;
 
        /*
         * RISC OS allows the use of '/' in directory entry names, so we need
         * to fix these up.  '/' is typically used for FAT compatibility to
         * represent '.', so do the same conversion here.  In any case, '.'
         * will never be in a RISC OS name since it is used as the pathname
-        * separator.
+        * separator.  Handle the case where we may generate a '.' or '..'
+        * name, replacing the first character with '^' (the RISC OS "parent
+        * directory" character.)
         */
-       for (i = 0; i < obj->name_len; i++)
-               if (obj->name[i] == '/')
+       for (i = dots = 0; i < obj->name_len; i++)
+               if (obj->name[i] == '/') {
                        obj->name[i] = '.';
+                       dots++;
+               }
+
+       if (obj->name_len <= 2 && dots == obj->name_len)
+               obj->name[0] = '^';
 
        obj->filetype = -1;