am 5347f0ff: Merge "Valid filenames have length limits!" into mnc-dev
* commit '5347f0ff3857baae7b889d24acd352cabcc9205b': Valid filenames have length limits!
This commit is contained in:
@@ -36,6 +36,7 @@ import android.content.res.TypedArray;
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.FileUtils;
|
||||
import android.os.PatternMatcher;
|
||||
import android.os.UserHandle;
|
||||
import android.text.TextUtils;
|
||||
@@ -1194,7 +1195,8 @@ public class PackageParser {
|
||||
}
|
||||
}
|
||||
|
||||
private static String validateName(String name, boolean requiresSeparator) {
|
||||
private static String validateName(String name, boolean requireSeparator,
|
||||
boolean requireFilename) {
|
||||
final int N = name.length();
|
||||
boolean hasSep = false;
|
||||
boolean front = true;
|
||||
@@ -1216,7 +1218,10 @@ public class PackageParser {
|
||||
}
|
||||
return "bad character '" + c + "'";
|
||||
}
|
||||
return hasSep || !requiresSeparator
|
||||
if (requireFilename && !FileUtils.isValidExtFilename(name)) {
|
||||
return "Invalid filename";
|
||||
}
|
||||
return hasSep || !requireSeparator
|
||||
? null : "must have at least one '.' separator";
|
||||
}
|
||||
|
||||
@@ -1240,7 +1245,7 @@ public class PackageParser {
|
||||
|
||||
final String packageName = attrs.getAttributeValue(null, "package");
|
||||
if (!"android".equals(packageName)) {
|
||||
final String error = validateName(packageName, true);
|
||||
final String error = validateName(packageName, true, true);
|
||||
if (error != null) {
|
||||
throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
|
||||
"Invalid manifest package: " + error);
|
||||
@@ -1252,7 +1257,7 @@ public class PackageParser {
|
||||
if (splitName.length() == 0) {
|
||||
splitName = null;
|
||||
} else {
|
||||
final String error = validateName(splitName, false);
|
||||
final String error = validateName(splitName, false, false);
|
||||
if (error != null) {
|
||||
throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
|
||||
"Invalid manifest split: " + error);
|
||||
@@ -1391,7 +1396,7 @@ public class PackageParser {
|
||||
String str = sa.getNonConfigurationString(
|
||||
com.android.internal.R.styleable.AndroidManifest_sharedUserId, 0);
|
||||
if (str != null && str.length() > 0) {
|
||||
String nameError = validateName(str, true);
|
||||
String nameError = validateName(str, true, false);
|
||||
if (nameError != null && !"android".equals(pkgName)) {
|
||||
outError[0] = "<manifest> specifies bad sharedUserId name \""
|
||||
+ str + "\": " + nameError;
|
||||
@@ -1973,7 +1978,7 @@ public class PackageParser {
|
||||
return null;
|
||||
}
|
||||
String subName = proc.substring(1);
|
||||
String nameError = validateName(subName, false);
|
||||
String nameError = validateName(subName, false, false);
|
||||
if (nameError != null) {
|
||||
outError[0] = "Invalid " + type + " name " + proc + " in package "
|
||||
+ pkg + ": " + nameError;
|
||||
@@ -1981,7 +1986,7 @@ public class PackageParser {
|
||||
}
|
||||
return (pkg + proc).intern();
|
||||
}
|
||||
String nameError = validateName(proc, true);
|
||||
String nameError = validateName(proc, true, false);
|
||||
if (nameError != null && !"system".equals(proc)) {
|
||||
outError[0] = "Invalid " + type + " name " + proc + " in package "
|
||||
+ pkg + ": " + nameError;
|
||||
|
||||
@@ -24,6 +24,8 @@ import android.util.Log;
|
||||
import android.util.Slog;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
@@ -34,6 +36,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.Objects;
|
||||
@@ -456,6 +459,7 @@ public class FileUtils {
|
||||
res.append('_');
|
||||
}
|
||||
}
|
||||
trimFilename(res, 255);
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
@@ -504,9 +508,31 @@ public class FileUtils {
|
||||
res.append('_');
|
||||
}
|
||||
}
|
||||
// Even though vfat allows 255 UCS-2 chars, we might eventually write to
|
||||
// ext4 through a FUSE layer, so use that limit.
|
||||
trimFilename(res, 255);
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static String trimFilename(String str, int maxBytes) {
|
||||
final StringBuilder res = new StringBuilder(str);
|
||||
trimFilename(res, maxBytes);
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
private static void trimFilename(StringBuilder res, int maxBytes) {
|
||||
byte[] raw = res.toString().getBytes(StandardCharsets.UTF_8);
|
||||
if (raw.length > maxBytes) {
|
||||
maxBytes -= 3;
|
||||
while (raw.length > maxBytes) {
|
||||
res.deleteCharAt(res.length() / 2);
|
||||
raw = res.toString().getBytes(StandardCharsets.UTF_8);
|
||||
}
|
||||
res.insert(res.length() / 2, "...");
|
||||
}
|
||||
}
|
||||
|
||||
public static String rewriteAfterRename(File beforeDir, File afterDir, String path) {
|
||||
if (path == null) return null;
|
||||
final File result = rewriteAfterRename(beforeDir, afterDir, new File(path));
|
||||
|
||||
@@ -232,6 +232,18 @@ public class FileUtilsTest extends AndroidTestCase {
|
||||
assertEquals("foo_bar__baz", FileUtils.buildValidFatFilename("foo?bar**baz"));
|
||||
}
|
||||
|
||||
public void testTrimFilename() throws Exception {
|
||||
assertEquals("short.txt", FileUtils.trimFilename("short.txt", 16));
|
||||
assertEquals("extrem...eme.txt", FileUtils.trimFilename("extremelylongfilename.txt", 16));
|
||||
|
||||
final String unicode = "a\u03C0\u03C0\u03C0\u03C0z";
|
||||
assertEquals("a\u03C0\u03C0\u03C0\u03C0z", FileUtils.trimFilename(unicode, 10));
|
||||
assertEquals("a\u03C0...\u03C0z", FileUtils.trimFilename(unicode, 9));
|
||||
assertEquals("a...\u03C0z", FileUtils.trimFilename(unicode, 8));
|
||||
assertEquals("a...\u03C0z", FileUtils.trimFilename(unicode, 7));
|
||||
assertEquals("a...z", FileUtils.trimFilename(unicode, 6));
|
||||
}
|
||||
|
||||
public void testBuildUniqueFile_normal() throws Exception {
|
||||
assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test"));
|
||||
assertNameEquals("test.jpg", FileUtils.buildUniqueFile(mTarget, "image/jpeg", "test.jpg"));
|
||||
|
||||
Reference in New Issue
Block a user