diff options
-rw-r--r-- | luni/src/main/java/libcore/net/MimeMap.java | 55 | ||||
-rw-r--r-- | luni/src/test/java/libcore/libcore/net/MimeMapTest.java | 29 |
2 files changed, 50 insertions, 34 deletions
diff --git a/luni/src/main/java/libcore/net/MimeMap.java b/luni/src/main/java/libcore/net/MimeMap.java index ba6a403297..76446b3e52 100644 --- a/luni/src/main/java/libcore/net/MimeMap.java +++ b/luni/src/main/java/libcore/net/MimeMap.java @@ -235,37 +235,42 @@ public final class MimeMap { } /** - * An element of a *mime.types file: A MIME type or an extension, with an optional - * prefix of "?" (if not overriding an earlier value). + * An element of a *mime.types file. */ static class Element { - final String s; + final String mimeOrExt; final boolean keepExisting; - public Element(String s) { - if (s.startsWith("?")) { + /** + * @param spec A MIME type or an extension, with an optional + * prefix of "?" (if not overriding an earlier value). + * @param isMimeSpec whether this Element denotes a MIME type (as opposed to an + * extension). + */ + private Element(String spec, boolean isMimeSpec) { + if (spec.startsWith("?")) { this.keepExisting = true; - this.s = lowercaseValidOrThrow(s.substring(1)); + this.mimeOrExt = toLowerCase(spec.substring(1)); } else { this.keepExisting = false; - this.s = lowercaseValidOrThrow(s); + this.mimeOrExt = toLowerCase(spec); } - } - - private static String lowercaseValidOrThrow(String s) { - String result = toLowerCase(s); - if (!isValidMimeTypeOrExtension(result)) { - throw new IllegalArgumentException("Invalid: " + s); + if (isMimeSpec) { + checkValidMimeType(mimeOrExt); + } else { + checkValidExtension(mimeOrExt); } - return result; } + + public static Element ofMimeSpec(String s) { return new Element(s, true); } + public static Element ofExtensionSpec(String s) { return new Element(s, false); } } private static String maybePut(Map<String, String> map, Element keyElement, String value) { if (keyElement.keepExisting) { - return map.putIfAbsent(keyElement.s, value); + return map.putIfAbsent(keyElement.mimeOrExt, value); } else { - return map.put(keyElement.s, value); + return map.put(keyElement.mimeOrExt, value); } } @@ -311,16 +316,16 @@ public final class MimeMap { @CorePlatformApi public Builder put(@NonNull String mimeSpec, @NonNull List<@NonNull String> extensionSpecs) { - Element mimeElement = new Element(mimeSpec); // validate mimeSpec unconditionally + Element mimeElement = Element.ofMimeSpec(mimeSpec); // validate mimeSpec unconditionally if (extensionSpecs.isEmpty()) { return this; } - Element firstExtensionElement = new Element(extensionSpecs.get(0)); - maybePut(mimeToExt, mimeElement, firstExtensionElement.s); - maybePut(extToMime, firstExtensionElement, mimeElement.s); + Element firstExtensionElement = Element.ofExtensionSpec(extensionSpecs.get(0)); + maybePut(mimeToExt, mimeElement, firstExtensionElement.mimeOrExt); + maybePut(extToMime, firstExtensionElement, mimeElement.mimeOrExt); for (String spec : extensionSpecs.subList(1, extensionSpecs.size())) { - Element element = new Element(spec); - maybePut(extToMime, element, mimeElement.s); + Element element = Element.ofExtensionSpec(spec); + maybePut(extToMime, element, mimeElement.mimeOrExt); } return this; } @@ -345,19 +350,19 @@ public final class MimeMap { } } - static boolean isValidMimeTypeOrExtension(String s) { + private static boolean isValidMimeTypeOrExtension(String s) { return s != null && !s.isEmpty() && !s.contains("?") && !s.contains(" ") && s.equals(toLowerCase(s)); } static void checkValidMimeType(String s) { - if (!isValidMimeTypeOrExtension(s)) { + if (!isValidMimeTypeOrExtension(s) || !s.contains("/")) { throw new IllegalArgumentException("Invalid MIME type: " + s); } } static void checkValidExtension(String s) { - if (!isValidMimeTypeOrExtension(s)) { + if (!isValidMimeTypeOrExtension(s) || s.contains("/")) { throw new IllegalArgumentException("Invalid extension: " + s); } } diff --git a/luni/src/test/java/libcore/libcore/net/MimeMapTest.java b/luni/src/test/java/libcore/libcore/net/MimeMapTest.java index 698e7e81f3..c54500805c 100644 --- a/luni/src/test/java/libcore/libcore/net/MimeMapTest.java +++ b/luni/src/test/java/libcore/libcore/net/MimeMapTest.java @@ -53,14 +53,14 @@ public class MimeMapTest { mimeMap = null; } - @Test public void invalidExtension() { + @Test public void lookup_invalidExtension() { assertNull(mimeMap.guessMimeTypeFromExtension(null)); assertNull(mimeMap.guessMimeTypeFromExtension("")); assertFalse(mimeMap.hasExtension(null)); assertFalse(mimeMap.hasExtension("")); } - @Test public void invalidMimeType() { + @Test public void lookup_invalidMimeType() { assertNull(mimeMap.guessExtensionFromMimeType(null)); assertNull(mimeMap.guessExtensionFromMimeType("")); assertFalse(mimeMap.hasMimeType(null)); @@ -205,19 +205,19 @@ public class MimeMapTest { // null or "" are not allowed for either MIME type or extension assertPutThrowsNpe(null, "ext"); assertPutThrowsIae("", "ext"); - assertPutThrowsNpe("mime", null); - assertPutThrowsIae("mime", ""); + assertPutThrowsNpe("mime/type", null); + assertPutThrowsIae("mime/type", ""); - assertPutThrowsNpe("mime", "ext", null); - assertPutThrowsIae("mime", "ext", ""); + assertPutThrowsNpe("mime/type", "ext", null); + assertPutThrowsIae("mime/type", "ext", ""); } @Test public void put_String_String_nullOrEmpty() { assertThrowsNpe(() -> MimeMap.builder().put(null, "ext")); assertThrowsIae(() -> MimeMap.builder().put("", "ext")); - assertThrowsNpe(() -> MimeMap.builder().put("mime", (String) null)); - assertThrowsIae(() -> MimeMap.builder().put("mime", "")); + assertThrowsNpe(() -> MimeMap.builder().put("mime/type", (String) null)); + assertThrowsIae(() -> MimeMap.builder().put("mime/type", "")); } /** @@ -311,7 +311,7 @@ public class MimeMapTest { /** * Tests invalid put() invocations that have '?' in additional/invalid places. */ - @Test public void put_additionalQuestionMarks() { + @Test public void put_invalid_additionalQuestionMarks() { // Potentially we could tolerate additional ? as a prefix in future, but right now we don't. assertPutThrowsIae("??text/plain", "txt"); assertPutThrowsIae("text/p?lain", "txt"); @@ -320,6 +320,17 @@ public class MimeMapTest { assertPutThrowsIae("text/plain", "t?xt"); } + /** Checks that MIME types must have a '/', while extensions must not. */ + @Test public void put_invalid_slash() { + assertPutThrowsIae("mime/type", "invalid/ext"); + assertPutThrowsIae("invalidmime", "ext"); + + // During lookups, wrong arguments return null rather than throwing. + mimeMap = MimeMap.builder().put("mime/type", "ext").build(); + assertNull(mimeMap.guessExtensionFromMimeType("ext")); // ext is no mime type + assertNull(mimeMap.guessMimeTypeFromExtension("mime/type")); // mime/type is no extension + } + private static void assertPutThrowsNpe(String mime, String... exts) { assertThrowsNpe(() -> MimeMap.builder().put(mime, Arrays.asList(exts))); } |