Skip to content

Commit 61f7736

Browse files
gregwjoakime
andauthored
Review UriCompliance.LEGACY behavior with bad UTF-8 in query (#12791)
* Added tests for DEFAULT, ALLOW_BAD_UTF8 and LEGACY. * LEGACY expectations are set to jetty-11 results * Added TRUNCATED_UTF8_ENCODING for LEGACY mode * Adding up-to-date tests for query extraction behavior. * Left `queryBehaviorsLegacy` alone, as expectations from Jetty 11. * The `queryBehaviorsDefault` expectations are based Jetty 12.0.16. * The `queryBehaviorsBadUtf8Allowed` has its expectations updated. --------- Co-authored-by: Joakim Erdfelt <[email protected]>
1 parent da942d0 commit 61f7736

File tree

11 files changed

+541
-127
lines changed

11 files changed

+541
-127
lines changed

jetty-core/jetty-http/src/main/java/org/eclipse/jetty/http/UriCompliance.java

+6-1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ public enum Violation implements ComplianceViolation
100100
*/
101101
BAD_UTF8_ENCODING("https://datatracker.ietf.org/doc/html/rfc5987#section-3.2.1", "Bad UTF-8 encoding"),
102102

103+
/**
104+
* Allow truncated UTF-8 encodings to be substituted by the replacement character.
105+
*/
106+
TRUNCATED_UTF8_ENCODING("https://datatracker.ietf.org/doc/html/rfc5987#section-3.2.1", "Truncated UTF-8 encoding"),
107+
103108
/**
104109
* Allow encoded path characters not allowed by the Servlet spec rules.
105110
*/
@@ -210,7 +215,7 @@ public String getDescription()
210215
Violation.AMBIGUOUS_PATH_SEPARATOR,
211216
Violation.AMBIGUOUS_PATH_ENCODING,
212217
Violation.AMBIGUOUS_EMPTY_SEGMENT,
213-
Violation.BAD_UTF8_ENCODING,
218+
Violation.TRUNCATED_UTF8_ENCODING,
214219
Violation.UTF16_ENCODINGS,
215220
Violation.USER_INFO));
216221

jetty-core/jetty-server/src/main/java/org/eclipse/jetty/server/Request.java

+27-15
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import java.util.function.Function;
3737
import java.util.function.Predicate;
3838

39+
import org.eclipse.jetty.http.BadMessageException;
3940
import org.eclipse.jetty.http.ComplianceViolation;
4041
import org.eclipse.jetty.http.HttpCookie;
4142
import org.eclipse.jetty.http.HttpFields;
@@ -559,27 +560,38 @@ static Fields extractQueryParameters(Request request)
559560

560561
static Fields extractQueryParameters(Request request, Charset charset)
561562
{
562-
String query = request.getHttpURI().getQuery();
563-
if (StringUtil.isBlank(query))
564-
return Fields.EMPTY;
565-
Fields fields = new Fields(true);
566-
567-
if (charset == null || StandardCharsets.UTF_8.equals(charset))
563+
UriCompliance uriCompliance = null;
564+
try
568565
{
569-
UriCompliance uriCompliance = request.getConnectionMetaData().getHttpConfiguration().getUriCompliance();
570-
boolean allowBadUtf8 = uriCompliance.allows(UriCompliance.Violation.BAD_UTF8_ENCODING);
571-
if (!UrlEncoded.decodeUtf8To(query, 0, query.length(), fields::add, allowBadUtf8))
566+
String query = request.getHttpURI().getQuery();
567+
if (StringUtil.isBlank(query))
568+
return Fields.EMPTY;
569+
Fields fields = new Fields(true);
570+
571+
if (charset == null || StandardCharsets.UTF_8.equals(charset))
572+
{
573+
uriCompliance = request.getConnectionMetaData().getHttpConfiguration().getUriCompliance();
574+
boolean allowTruncatedUtf8 = uriCompliance.allows(UriCompliance.Violation.TRUNCATED_UTF8_ENCODING);
575+
boolean allowBadUtf8 = uriCompliance.allows(UriCompliance.Violation.BAD_UTF8_ENCODING);
576+
if (!UrlEncoded.decodeUtf8To(query, 0, query.length(), fields::add, allowTruncatedUtf8, allowBadUtf8))
577+
{
578+
HttpChannel httpChannel = HttpChannel.from(request);
579+
if (httpChannel != null && httpChannel.getComplianceViolationListener() != null)
580+
httpChannel.getComplianceViolationListener().onComplianceViolation(new ComplianceViolation.Event(uriCompliance, UriCompliance.Violation.BAD_UTF8_ENCODING, "query=" + query));
581+
}
582+
}
583+
else
572584
{
573-
HttpChannel httpChannel = HttpChannel.from(request);
574-
if (httpChannel != null && httpChannel.getComplianceViolationListener() != null)
575-
httpChannel.getComplianceViolationListener().onComplianceViolation(new ComplianceViolation.Event(uriCompliance, UriCompliance.Violation.BAD_UTF8_ENCODING, "query=" + query));
585+
UrlEncoded.decodeTo(query, fields::add, charset);
576586
}
587+
return fields;
577588
}
578-
else
589+
catch (Throwable t)
579590
{
580-
UrlEncoded.decodeTo(query, fields::add, charset);
591+
// if (uriCompliance == UriCompliance.LEGACY)
592+
// throw t;
593+
throw new BadMessageException("Bad query", t);
581594
}
582-
return fields;
583595
}
584596

585597
static Fields getParameters(Request request) throws Exception

jetty-core/jetty-server/src/test/java/org/eclipse/jetty/server/FormFieldsTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public static Stream<Arguments> invalidData()
111111
Arguments.of(List.of("name%"), UTF_8, -1, -1, IllegalStateException.class),
112112
Arguments.of(List.of("name%A"), UTF_8, -1, -1, IllegalStateException.class),
113113

114-
Arguments.of(List.of("name%A="), UTF_8, -1, -1, CharacterCodingException.class),
114+
Arguments.of(List.of("name%A="), UTF_8, -1, -1, IllegalArgumentException.class),
115115
Arguments.of(List.of("name%A&"), UTF_8, -1, -1, IllegalArgumentException.class),
116116

117117
Arguments.of(List.of("name=%"), UTF_8, -1, -1, IllegalStateException.class),

0 commit comments

Comments
 (0)