diff options
| author | Jeff Sharkey <jsharkey@android.com> | 2014-11-26 13:38:26 -0800 |
|---|---|---|
| committer | Jeff Sharkey <jsharkey@android.com> | 2014-12-01 09:38:49 -0800 |
| commit | 0cce5355b45d835f95a8918b8b803fd977d374e4 (patch) | |
| tree | d42b69e266761ba6caed601f5d710df9d9739bb5 /core/java/android/os/FileUtils.java | |
| parent | 48e17629b0b6c89cb77342c0364a1cf3a0b2a0fb (diff) | |
Sanitize display names, keep extensions intact.
When creating or renaming files on external storage, sanitize the
requested display names to be valid FAT filenames. This also fixes
a handful of directory traversal bugs.
Also relax logic around generating display names to allow any
extension which maps to the requested MIME type. Tests to verify.
Bug: 18512473, 18504132
Change-Id: I89e632019ee145f53d9d9d2050932f8939a756af
Diffstat (limited to 'core/java/android/os/FileUtils.java')
| -rw-r--r-- | core/java/android/os/FileUtils.java | 80 |
1 files changed, 74 insertions, 6 deletions
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index fe47f5b84d3f..0a724a1d881f 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -17,9 +17,8 @@ package android.os; import android.system.ErrnoException; -import android.text.TextUtils; import android.system.Os; -import android.system.OsConstants; +import android.text.TextUtils; import android.util.Log; import android.util.Slog; @@ -403,20 +402,89 @@ public class FileUtils { return success; } + private static boolean isValidExtFilenameChar(char c) { + switch (c) { + case '\0': + case '/': + return false; + default: + return true; + } + } + /** - * Assert that given filename is valid on ext4. + * Check if given filename is valid for an ext4 filesystem. */ public static boolean isValidExtFilename(String name) { + return (name != null) && name.equals(buildValidExtFilename(name)); + } + + /** + * Mutate the given filename to make it valid for an ext4 filesystem, + * replacing any invalid characters with "_". + */ + public static String buildValidExtFilename(String name) { if (TextUtils.isEmpty(name) || ".".equals(name) || "..".equals(name)) { - return false; + return "(invalid)"; } + final StringBuilder res = new StringBuilder(name.length()); for (int i = 0; i < name.length(); i++) { final char c = name.charAt(i); - if (c == '\0' || c == '/') { + if (isValidExtFilenameChar(c)) { + res.append(c); + } else { + res.append('_'); + } + } + return res.toString(); + } + + private static boolean isValidFatFilenameChar(char c) { + if ((0x00 <= c && c <= 0x1f)) { + return false; + } + switch (c) { + case '"': + case '*': + case '/': + case ':': + case '<': + case '>': + case '?': + case '\\': + case '|': + case 0x7F: return false; + default: + return true; + } + } + + /** + * Check if given filename is valid for a FAT filesystem. + */ + public static boolean isValidFatFilename(String name) { + return (name != null) && name.equals(buildValidFatFilename(name)); + } + + /** + * Mutate the given filename to make it valid for a FAT filesystem, + * replacing any invalid characters with "_". + */ + public static String buildValidFatFilename(String name) { + if (TextUtils.isEmpty(name) || ".".equals(name) || "..".equals(name)) { + return "(invalid)"; + } + final StringBuilder res = new StringBuilder(name.length()); + for (int i = 0; i < name.length(); i++) { + final char c = name.charAt(i); + if (isValidFatFilenameChar(c)) { + res.append(c); + } else { + res.append('_'); } } - return true; + return res.toString(); } public static String rewriteAfterRename(File beforeDir, File afterDir, String path) { |
