Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions android/guava-tests/test/com/google/common/net/MediaTypeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,18 @@ public void testWithParameter_nonAsciiParameterValue() {
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "…"));
}

public void testWithParameter_controlCharacterInParameterValue() {
MediaType mediaType = MediaType.parse("text/plain");
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "a\r\nb"));
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "a\nb"));
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "a\rb"));
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "a\u0000b"));
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "a\u007fb"));
assertThat(mediaType.withParameter("a", "a\tb"))
.isEqualTo(MediaType.parse("text/plain; a=\"a\tb\""));
assertThat(mediaType.withParameter("a", "a\tb").toString()).isEqualTo("text/plain; a=\"a\tb\"");
}

public void testWithParameter_emptyParameter() {
MediaType mediaType = MediaType.parse("text/plain");
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("", "a"));
Expand Down Expand Up @@ -377,6 +389,15 @@ public void testParse_badInput() {
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=1; b"));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=1; b="));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\u2025"));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\r\nc\""));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\nc\""));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\rc\""));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\\\rc\""));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\\\nc\""));
assertThrows(
IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\u0000c\""));
assertThrows(
IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\\\u0000c\""));
}

// https://github.com/google/guava/issues/6663
Expand Down
14 changes: 11 additions & 3 deletions android/guava/src/com/google/common/net/MediaType.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ public final class MediaType {
.and(CharMatcher.isNot(' '))
.and(CharMatcher.noneOf("()<>@,;:\\\"/[]?="));

private static final CharMatcher QUOTED_TEXT_MATCHER = ascii().and(CharMatcher.noneOf("\"\\\r"));
private static final CharMatcher PARAMETER_VALUE_MATCHER =
ascii().and(javaIsoControl().negate()).or(CharMatcher.is('\t'));

private static final CharMatcher QUOTED_TEXT_MATCHER =
PARAMETER_VALUE_MATCHER.and(CharMatcher.noneOf("\"\\"));

/*
* This matches the same characters as linear-white-space from RFC 822, but we make no effort to
Expand Down Expand Up @@ -1242,6 +1246,10 @@ private static String normalizeToken(String token) {
private static String normalizeParameterValue(String attribute, String value) {
checkNotNull(value); // for GWT
checkArgument(ascii().matchesAllOf(value), "parameter values must be ASCII: %s", value);
checkArgument(
PARAMETER_VALUE_MATCHER.matchesAllOf(value),
"parameter values must not contain control characters: %s",
value);
return attribute.equals(CHARSET_ATTRIBUTE) ? Ascii.toLowerCase(value) : value;
}

Expand Down Expand Up @@ -1270,7 +1278,7 @@ public static MediaType parse(String input) {
while (tokenizer.previewChar() != '"') {
if (tokenizer.previewChar() == '\\') {
tokenizer.consumeCharacter('\\');
valueBuilder.append(tokenizer.consumeCharacter(ascii()));
valueBuilder.append(tokenizer.consumeCharacter(PARAMETER_VALUE_MATCHER));
} else {
valueBuilder.append(tokenizer.consumeToken(QUOTED_TEXT_MATCHER));
}
Expand Down Expand Up @@ -1406,7 +1414,7 @@ private static String escapeAndQuote(String value) {
StringBuilder escaped = new StringBuilder(value.length() + 16).append('"');
for (int i = 0; i < value.length(); i++) {
char ch = value.charAt(i);
if (ch == '\r' || ch == '\\' || ch == '"') {
if (ch == '\\' || ch == '"') {
escaped.append('\\');
}
escaped.append(ch);
Expand Down
21 changes: 21 additions & 0 deletions guava-tests/test/com/google/common/net/MediaTypeTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,18 @@ public void testWithParameter_nonAsciiParameterValue() {
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "…"));
}

public void testWithParameter_controlCharacterInParameterValue() {
MediaType mediaType = MediaType.parse("text/plain");
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "a\r\nb"));
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "a\nb"));
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "a\rb"));
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "a\u0000b"));
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("a", "a\u007fb"));
assertThat(mediaType.withParameter("a", "a\tb"))
.isEqualTo(MediaType.parse("text/plain; a=\"a\tb\""));
assertThat(mediaType.withParameter("a", "a\tb").toString()).isEqualTo("text/plain; a=\"a\tb\"");
}

public void testWithParameter_emptyParameter() {
MediaType mediaType = MediaType.parse("text/plain");
assertThrows(IllegalArgumentException.class, () -> mediaType.withParameter("", "a"));
Expand Down Expand Up @@ -377,6 +389,15 @@ public void testParse_badInput() {
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=1; b"));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=1; b="));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\u2025"));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\r\nc\""));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\nc\""));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\rc\""));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\\\rc\""));
assertThrows(IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\\\nc\""));
assertThrows(
IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\u0000c\""));
assertThrows(
IllegalArgumentException.class, () -> MediaType.parse("text/plain; a=\"b\\\u0000c\""));
}

// https://github.com/google/guava/issues/6663
Expand Down
14 changes: 11 additions & 3 deletions guava/src/com/google/common/net/MediaType.java
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ public final class MediaType {
.and(CharMatcher.isNot(' '))
.and(CharMatcher.noneOf("()<>@,;:\\\"/[]?="));

private static final CharMatcher QUOTED_TEXT_MATCHER = ascii().and(CharMatcher.noneOf("\"\\\r"));
private static final CharMatcher PARAMETER_VALUE_MATCHER =
ascii().and(javaIsoControl().negate()).or(CharMatcher.is('\t'));

private static final CharMatcher QUOTED_TEXT_MATCHER =
PARAMETER_VALUE_MATCHER.and(CharMatcher.noneOf("\"\\"));

/*
* This matches the same characters as linear-white-space from RFC 822, but we make no effort to
Expand Down Expand Up @@ -1242,6 +1246,10 @@ private static String normalizeToken(String token) {
private static String normalizeParameterValue(String attribute, String value) {
checkNotNull(value); // for GWT
checkArgument(ascii().matchesAllOf(value), "parameter values must be ASCII: %s", value);
checkArgument(
PARAMETER_VALUE_MATCHER.matchesAllOf(value),
"parameter values must not contain control characters: %s",
value);
return attribute.equals(CHARSET_ATTRIBUTE) ? Ascii.toLowerCase(value) : value;
}

Expand Down Expand Up @@ -1270,7 +1278,7 @@ public static MediaType parse(String input) {
while (tokenizer.previewChar() != '"') {
if (tokenizer.previewChar() == '\\') {
tokenizer.consumeCharacter('\\');
valueBuilder.append(tokenizer.consumeCharacter(ascii()));
valueBuilder.append(tokenizer.consumeCharacter(PARAMETER_VALUE_MATCHER));
} else {
valueBuilder.append(tokenizer.consumeToken(QUOTED_TEXT_MATCHER));
}
Expand Down Expand Up @@ -1406,7 +1414,7 @@ private static String escapeAndQuote(String value) {
StringBuilder escaped = new StringBuilder(value.length() + 16).append('"');
for (int i = 0; i < value.length(); i++) {
char ch = value.charAt(i);
if (ch == '\r' || ch == '\\' || ch == '"') {
if (ch == '\\' || ch == '"') {
escaped.append('\\');
}
escaped.append(ch);
Expand Down
Loading