]> git.ipfire.org Git - thirdparty/e2fsprogs.git/commitdiff
debugfs: avoid ambiguity when printing filenames
authorEric Biggers <ebiggers@google.com>
Sun, 28 Apr 2019 23:42:41 +0000 (19:42 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Sun, 28 Apr 2019 23:42:41 +0000 (19:42 -0400)
The way debugfs escapes filenames is ambiguous because a sequence like
M-A can mean either the byte 'A' + 128 == 0xc1 or the three bytes
{'M', '-', 'A'}.  Similarly, ^A can mean either the byte
'A' ^ 0x40 == 0x01 or the two bytes {'^', 'A'}.

Fix this and simplify the code by switching to a simpler strategy where
all bytes < 32, all bytes >= 127, and backslash are encoded with C-style
hex escape sequences.  E.g., the byte 0xc1 will now be encoded as \xc1
rather than M-A as it was before, while a filename consisting of the
three bytes {'M', '-', 'A'} will continue to be shown as M-A.

I want to fix this mainly because I want to use debugfs to retrieve raw
encrypted filenames for ciphertext verification tests.  But this doesn't
work if the returned filenames are ambiguous.

Fixes: 68a1de3df340 ("debugfs: pretty print encrypted filenames in the ls command")
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
debugfs/ls.c

index 41af15d2bea46f48e9926b81550c66d3e7ff1dbe..4f63bd3fd92af1d6ea0bf97ec38444ab9b407d3d 100644 (file)
@@ -62,21 +62,15 @@ static int print_filename(FILE *f, struct ext2_dir_entry *dirent, int options)
        }
        while (len--) {
                ch = *cp++;
-               if (ch > 128) {
+               if (ch < 32 || ch >= 127 || ch == '\\') {
                        if (f)
-                               fputs("M-", f);
-                       ch -= 128;
-                       retlen += 2;
-               }
-               if ((ch < 32) || (ch == 0x7f)) {
+                               fprintf(f, "\\x%02x", ch);
+                       retlen += 4;
+               } else {
                        if (f)
-                               fputc('^', f);
-                       ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
+                               fputc(ch, f);
                        retlen++;
                }
-               if (f)
-                       fputc(ch, f);
-               retlen++;
        }
        return retlen;
 }