From 33fe1fd7e374f20ac6a5d04e081b7423f471b07c Mon Sep 17 00:00:00 2001 From: Bongjae Chang Date: Sat, 14 Sep 2024 21:33:03 +0900 Subject: [PATCH 01/16] Issue #2212 Enhances validation of HTTP header names --- .../grizzly/http/HttpCodecFilter.java | 57 ++++++++++++++++--- .../grizzly/http/HttpRequestParseTest.java | 55 +++++++++++++++++- 2 files changed, 100 insertions(+), 12 deletions(-) diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java index 49bdd6be29..bc5061c4af 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -37,6 +37,7 @@ import org.glassfish.grizzly.http.util.ByteChunk; import org.glassfish.grizzly.http.util.CacheableDataChunk; import org.glassfish.grizzly.http.util.Constants; +import org.glassfish.grizzly.http.util.CookieHeaderParser; import org.glassfish.grizzly.http.util.DataChunk; import org.glassfish.grizzly.http.util.Header; import org.glassfish.grizzly.http.util.MimeHeaders; @@ -707,8 +708,13 @@ protected boolean parseHeaderFromBytes(final HttpHeader httpHeader, final MimeHe parsingState.subState++; } case 1: { // parse header name - if (!parseHeaderName(httpHeader, mimeHeaders, parsingState, input, end)) { + final int result = parseHeaderName(httpHeader, mimeHeaders, parsingState, input, end); + if (result == -1) { return false; + } else if (result == -2) { // EOL. ignore field-lines + parsingState.subState = 0; + parsingState.start = -1; + return true; } parsingState.subState++; @@ -754,7 +760,7 @@ protected boolean parseHeaderFromBytes(final HttpHeader httpHeader, final MimeHe } } - protected boolean parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mimeHeaders, final HeaderParsingState parsingState, final byte[] input, + protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mimeHeaders, final HeaderParsingState parsingState, final byte[] input, final int end) { final int arrayOffs = parsingState.arrayOffset; @@ -770,19 +776,33 @@ protected boolean parseHeaderName(final HttpHeader httpHeader, final MimeHeaders parsingState.offset = offset + 1 - arrayOffs; finalizeKnownHeaderNames(httpHeader, parsingState, input, start, offset); - return true; + return 0; } else if (b >= Constants.A && b <= Constants.Z) { if (!preserveHeaderCase) { b -= Constants.LC_OFFSET; } input[offset] = b; + } else if (b == Constants.CR) { + parsingState.offset = offset - arrayOffs; + final int eol = checkEOL(parsingState, input, end); + if (eol == 0) { // EOL + // the offset is already increased in the check + return -2; + } else if (eol == -2) { // not enough data + // by keeping the offset unchanged, we will recheck the EOL at the next opportunity. + break; + } } + if (!CookieHeaderParser.isToken(b)) { + throw new IllegalStateException( + "An invalid character 0x" + Integer.toHexString(b) + " was found in the header name"); + } offset++; } parsingState.offset = offset - arrayOffs; - return false; + return -1; } protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderParsingState parsingState, final byte[] input, final int end) { @@ -963,8 +983,13 @@ protected boolean parseHeaderFromBuffer(final HttpHeader httpHeader, final MimeH parsingState.subState++; } case 1: { // parse header name - if (!parseHeaderName(httpHeader, mimeHeaders, parsingState, input)) { + final int result = parseHeaderName(httpHeader, mimeHeaders, parsingState, input); + if (result == -1) { return false; + } else if (result == -2) { // EOL. ignore field-lines + parsingState.subState = 0; + parsingState.start = -1; + return true; } parsingState.subState++; @@ -1010,7 +1035,7 @@ protected boolean parseHeaderFromBuffer(final HttpHeader httpHeader, final MimeH } } - protected boolean parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mimeHeaders, final HeaderParsingState parsingState, final Buffer input) { + protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mimeHeaders, final HeaderParsingState parsingState, final Buffer input) { final int limit = Math.min(input.limit(), parsingState.packetLimit); final int start = parsingState.start; int offset = parsingState.offset; @@ -1023,19 +1048,33 @@ protected boolean parseHeaderName(final HttpHeader httpHeader, final MimeHeaders parsingState.offset = offset + 1; finalizeKnownHeaderNames(httpHeader, parsingState, input, start, offset); - return true; + return 0; } else if (b >= Constants.A && b <= Constants.Z) { if (!preserveHeaderCase) { b -= Constants.LC_OFFSET; } input.put(offset, b); + } else if (b == Constants.CR) { + parsingState.offset = offset; + final int eol = checkEOL(parsingState, input); + if (eol == 0) { // EOL + // the offset is already increased in the check + return -2; + } else if (eol == -2) { // not enough data + // by keeping the offset unchanged, we will recheck the EOL at the next opportunity. + break; + } } + if (!CookieHeaderParser.isToken(b)) { + throw new IllegalStateException( + "An invalid character 0x" + Integer.toHexString(b) + " was found in the header name"); + } offset++; } parsingState.offset = offset; - return false; + return -1; } protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderParsingState parsingState, final Buffer input) { diff --git a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java index 79c10e622a..6d81a74e97 100644 --- a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java +++ b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -81,6 +81,42 @@ public void testSimpleHeadersPreserveCase() throws Exception { doHttpRequestTest("POST", "/index.html", "HTTP/1.1", headers, "\r\n", true); } + public void testDisallowedHeaders() { + final StringBuilder sb = new StringBuilder("GET / HTTP/1.1\r\n"); + sb.append("Host: localhost\r\n"); + sb.append(new char[]{0x00, 0x01, 0x02, '\t', '\n', '\r', ' ', '\"', '(', ')', '/', ';', '<', '=', '>', '?', '@', + '[', 0x5c, ']', '{', '}'}).append(": some-value\r\n"); + sb.append("\r\n"); + try { + doTestDecoder(sb.toString(), 128); + fail("Bad HTTP headers exception had to be thrown"); + } catch (IllegalStateException e) { + // expected + } + try { + doTestDecoder("GET /index.html HTTP/1.1\nHost: localhost\nContent -Length: 1234\n\n", 128); + fail("Bad HTTP headers exception had to be thrown"); + } catch (IllegalStateException e) { + // expected + } + try { + doTestDecoder("GET /index.html HTTP/1.1\nHost: localhost\nContent-\rLength: 1234\n\n", 128); + fail("Bad HTTP headers exception had to be thrown"); + } catch (IllegalStateException e) { + // expected + } + } + + public void testIgnoredHeaders() throws Exception { + final Map> headers = new HashMap<>(); + headers.put("Host", new Pair<>("localhost", "localhost")); + headers.put("Ignore\r\nContent-length", new Pair<>("2345", "2345")); + final Map> expectedHeaders = new HashMap<>(); + expectedHeaders.put("Host", new Pair<>("localhost", "localhost")); + expectedHeaders.put("Content-length", new Pair<>("2345", "2345")); + doHttpRequestTest("POST", "/index.html", "HTTP/1.1", headers, expectedHeaders, "\r\n"); + } + public void testMultiLineHeaders() throws Exception { Map> headers = new HashMap<>(); headers.put("Host", new Pair<>("localhost", "localhost")); @@ -204,16 +240,29 @@ private void doHttpRequestTest(String method, String requestURI, String protocol new Pair<>(protocol, protocol), headers, eol, false); } + private void doHttpRequestTest(String method, String requestURI, String protocol, + Map> headers, + Map> expectedHeaders, String eol) throws Exception { + doHttpRequestTest(new Pair<>(method, method), new Pair<>(requestURI, requestURI), + new Pair<>(protocol, protocol), headers, expectedHeaders, eol, false); + } + private void doHttpRequestTest(String method, String requestURI, String protocol, Map> headers, String eol, boolean preserveCase) throws Exception { doHttpRequestTest(new Pair<>(method, method), new Pair<>(requestURI, requestURI), new Pair<>(protocol, protocol), headers, eol, preserveCase); } - @SuppressWarnings("unchecked") private void doHttpRequestTest(Pair method, Pair requestURI, Pair protocol, Map> headers, String eol, boolean preserveHeaderCase) throws Exception { + doHttpRequestTest(method, requestURI, protocol, headers, headers, eol, preserveHeaderCase); + } + @SuppressWarnings("unchecked") + private void doHttpRequestTest(Pair method, Pair requestURI, + Pair protocol, Map> headers, + Map> expectedHeaders, String eol, + boolean preserveHeaderCase) throws Exception { final FutureImpl parseResult = SafeFutureImpl.create(); Connection connection = null; @@ -222,7 +271,7 @@ private void doHttpRequestTest(Pair method, Pair serverFilter.setPreserveHeaderCase(preserveHeaderCase); FilterChainBuilder filterChainBuilder = FilterChainBuilder.stateless().add(new TransportFilter()).add(new ChunkingFilter(2)).add(serverFilter) - .add(new HTTPRequestCheckFilter(parseResult, method, requestURI, protocol, headers, preserveHeaderCase)); + .add(new HTTPRequestCheckFilter(parseResult, method, requestURI, protocol, expectedHeaders == null ? headers : expectedHeaders, preserveHeaderCase)); TCPNIOTransport transport = TCPNIOTransportBuilder.newInstance().build(); transport.setProcessor(filterChainBuilder.build()); From 302c7e8a01d114e0d39ebef0e5d2257cb4b78bcb Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Thu, 24 Oct 2024 15:12:49 -0600 Subject: [PATCH 02/16] FISH-9690: testing fix from contributor --- boms/bom/pom.xml | 2 +- extras/bundles/grizzly-httpservice-bundle/pom.xml | 2 +- extras/bundles/pom.xml | 2 +- extras/connection-pool/pom.xml | 2 +- extras/grizzly-httpservice/pom.xml | 2 +- extras/http-server-jaxws/pom.xml | 2 +- extras/http-server-multipart/pom.xml | 2 +- extras/http-servlet-extras/pom.xml | 2 +- extras/pom.xml | 2 +- extras/tls-sni/pom.xml | 2 +- modules/bundles/comet/pom.xml | 2 +- modules/bundles/core/pom.xml | 2 +- modules/bundles/http-all/pom.xml | 2 +- modules/bundles/http-servlet/pom.xml | 2 +- modules/bundles/http/pom.xml | 2 +- modules/bundles/pom.xml | 2 +- modules/bundles/websockets/pom.xml | 2 +- modules/comet/pom.xml | 2 +- modules/grizzly/pom.xml | 2 +- modules/http-ajp/pom.xml | 2 +- modules/http-server/pom.xml | 2 +- modules/http-servlet/pom.xml | 2 +- modules/http/pom.xml | 2 +- modules/http2/pom.xml | 2 +- modules/monitoring/grizzly/pom.xml | 2 +- modules/monitoring/http-server/pom.xml | 2 +- modules/monitoring/http/pom.xml | 2 +- modules/monitoring/pom.xml | 2 +- modules/pom.xml | 2 +- modules/portunif/pom.xml | 2 +- modules/websockets/pom.xml | 2 +- pom.xml | 4 ++-- samples/connection-pool-samples/pom.xml | 2 +- samples/framework-samples/pom.xml | 2 +- samples/http-ajp-samples/pom.xml | 2 +- samples/http-jaxws-samples/pom.xml | 2 +- samples/http-multipart-samples/pom.xml | 2 +- samples/http-samples/pom.xml | 2 +- samples/http-server-samples/pom.xml | 2 +- samples/pom.xml | 2 +- samples/portunif/pom.xml | 2 +- samples/tls-sni-samples/pom.xml | 2 +- 42 files changed, 43 insertions(+), 43 deletions(-) diff --git a/boms/bom/pom.xml b/boms/bom/pom.xml index 7c490a4c39..65f2ebd4a7 100644 --- a/boms/bom/pom.xml +++ b/boms/bom/pom.xml @@ -30,7 +30,7 @@ org.glassfish.grizzly grizzly-bom - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT pom grizzly-bom diff --git a/extras/bundles/grizzly-httpservice-bundle/pom.xml b/extras/bundles/grizzly-httpservice-bundle/pom.xml index fb11106d63..8ff4270e54 100644 --- a/extras/bundles/grizzly-httpservice-bundle/pom.xml +++ b/extras/bundles/grizzly-httpservice-bundle/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/extras/bundles/pom.xml b/extras/bundles/pom.xml index 4fe1203447..705af2e88f 100644 --- a/extras/bundles/pom.xml +++ b/extras/bundles/pom.xml @@ -23,7 +23,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/connection-pool/pom.xml b/extras/connection-pool/pom.xml index 9696490075..00402901ef 100644 --- a/extras/connection-pool/pom.xml +++ b/extras/connection-pool/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/grizzly-httpservice/pom.xml b/extras/grizzly-httpservice/pom.xml index 00bd2f4fff..cc84731c7a 100644 --- a/extras/grizzly-httpservice/pom.xml +++ b/extras/grizzly-httpservice/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/http-server-jaxws/pom.xml b/extras/http-server-jaxws/pom.xml index 3f5e060a0c..9620fed487 100644 --- a/extras/http-server-jaxws/pom.xml +++ b/extras/http-server-jaxws/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/http-server-multipart/pom.xml b/extras/http-server-multipart/pom.xml index 7452afae8f..4e45c33903 100644 --- a/extras/http-server-multipart/pom.xml +++ b/extras/http-server-multipart/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/http-servlet-extras/pom.xml b/extras/http-servlet-extras/pom.xml index 20d981e809..ec56ab1497 100644 --- a/extras/http-servlet-extras/pom.xml +++ b/extras/http-servlet-extras/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/pom.xml b/extras/pom.xml index ee48c25e18..ae6a00a5f3 100644 --- a/extras/pom.xml +++ b/extras/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../pom.xml diff --git a/extras/tls-sni/pom.xml b/extras/tls-sni/pom.xml index 9ed3bbf2c5..1d2b370299 100644 --- a/extras/tls-sni/pom.xml +++ b/extras/tls-sni/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/bundles/comet/pom.xml b/modules/bundles/comet/pom.xml index 5586b1a49f..15418670ff 100644 --- a/modules/bundles/comet/pom.xml +++ b/modules/bundles/comet/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/bundles/core/pom.xml b/modules/bundles/core/pom.xml index 0069b153e7..db92c746ff 100644 --- a/modules/bundles/core/pom.xml +++ b/modules/bundles/core/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/bundles/http-all/pom.xml b/modules/bundles/http-all/pom.xml index 2abe61393c..ae301dc318 100644 --- a/modules/bundles/http-all/pom.xml +++ b/modules/bundles/http-all/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/bundles/http-servlet/pom.xml b/modules/bundles/http-servlet/pom.xml index 08e99393b6..c1fab056a0 100755 --- a/modules/bundles/http-servlet/pom.xml +++ b/modules/bundles/http-servlet/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/bundles/http/pom.xml b/modules/bundles/http/pom.xml index ce831d01f0..17f63e7a4e 100755 --- a/modules/bundles/http/pom.xml +++ b/modules/bundles/http/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/bundles/pom.xml b/modules/bundles/pom.xml index 85abfd5341..c30e27dfe2 100644 --- a/modules/bundles/pom.xml +++ b/modules/bundles/pom.xml @@ -23,7 +23,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/bundles/websockets/pom.xml b/modules/bundles/websockets/pom.xml index 4753cf80c8..77fc9e31ee 100644 --- a/modules/bundles/websockets/pom.xml +++ b/modules/bundles/websockets/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/comet/pom.xml b/modules/comet/pom.xml index 3f58fb53d0..207040e7ad 100644 --- a/modules/comet/pom.xml +++ b/modules/comet/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/grizzly/pom.xml b/modules/grizzly/pom.xml index e9b97db781..bccc0f744e 100644 --- a/modules/grizzly/pom.xml +++ b/modules/grizzly/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/http-ajp/pom.xml b/modules/http-ajp/pom.xml index aa4a05ee0c..ac089cb48e 100755 --- a/modules/http-ajp/pom.xml +++ b/modules/http-ajp/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/http-server/pom.xml b/modules/http-server/pom.xml index 15a29ed0bc..402e1384df 100644 --- a/modules/http-server/pom.xml +++ b/modules/http-server/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/http-servlet/pom.xml b/modules/http-servlet/pom.xml index 92896fea7d..58101df9e5 100755 --- a/modules/http-servlet/pom.xml +++ b/modules/http-servlet/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/http/pom.xml b/modules/http/pom.xml index 6bef3d0fc4..f61427ae57 100644 --- a/modules/http/pom.xml +++ b/modules/http/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/http2/pom.xml b/modules/http2/pom.xml index 78ff4454be..2e63d9d01b 100644 --- a/modules/http2/pom.xml +++ b/modules/http2/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/monitoring/grizzly/pom.xml b/modules/monitoring/grizzly/pom.xml index d6d39e8249..354479b8dc 100644 --- a/modules/monitoring/grizzly/pom.xml +++ b/modules/monitoring/grizzly/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/monitoring/http-server/pom.xml b/modules/monitoring/http-server/pom.xml index bbb466dcbb..894833f9a6 100644 --- a/modules/monitoring/http-server/pom.xml +++ b/modules/monitoring/http-server/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/monitoring/http/pom.xml b/modules/monitoring/http/pom.xml index 40c9266f45..4bcfa5aabc 100644 --- a/modules/monitoring/http/pom.xml +++ b/modules/monitoring/http/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/monitoring/pom.xml b/modules/monitoring/pom.xml index 48cebe266a..a7276ca071 100644 --- a/modules/monitoring/pom.xml +++ b/modules/monitoring/pom.xml @@ -23,7 +23,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/pom.xml b/modules/pom.xml index eba6ea6373..b87d403cae 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -23,7 +23,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT grizzly-modules diff --git a/modules/portunif/pom.xml b/modules/portunif/pom.xml index 3960f18a03..15e447a120 100644 --- a/modules/portunif/pom.xml +++ b/modules/portunif/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/websockets/pom.xml b/modules/websockets/pom.xml index 9088e67b6d..3cfa9a45d0 100644 --- a/modules/websockets/pom.xml +++ b/modules/websockets/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/pom.xml b/pom.xml index 6f30a6195f..04ecee2ebc 100644 --- a/pom.xml +++ b/pom.xml @@ -24,12 +24,12 @@ org.glassfish.grizzly grizzly-bom - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT boms/bom/pom.xml grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT pom grizzly-project diff --git a/samples/connection-pool-samples/pom.xml b/samples/connection-pool-samples/pom.xml index b2c385cbf0..57ef825122 100755 --- a/samples/connection-pool-samples/pom.xml +++ b/samples/connection-pool-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/framework-samples/pom.xml b/samples/framework-samples/pom.xml index ac67858a68..af9eaaa34e 100755 --- a/samples/framework-samples/pom.xml +++ b/samples/framework-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/http-ajp-samples/pom.xml b/samples/http-ajp-samples/pom.xml index 2b7878ace1..658354d042 100644 --- a/samples/http-ajp-samples/pom.xml +++ b/samples/http-ajp-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/http-jaxws-samples/pom.xml b/samples/http-jaxws-samples/pom.xml index c726d50df4..3b5a6ac83d 100644 --- a/samples/http-jaxws-samples/pom.xml +++ b/samples/http-jaxws-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/http-multipart-samples/pom.xml b/samples/http-multipart-samples/pom.xml index c8a3fe4428..0d7aa98100 100644 --- a/samples/http-multipart-samples/pom.xml +++ b/samples/http-multipart-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/http-samples/pom.xml b/samples/http-samples/pom.xml index 53697b1125..ecbe4a33fb 100755 --- a/samples/http-samples/pom.xml +++ b/samples/http-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/http-server-samples/pom.xml b/samples/http-server-samples/pom.xml index c822631252..f3a10bc24a 100644 --- a/samples/http-server-samples/pom.xml +++ b/samples/http-server-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/pom.xml b/samples/pom.xml index ac06f12411..7336b092c3 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -17,7 +17,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../pom.xml diff --git a/samples/portunif/pom.xml b/samples/portunif/pom.xml index 547cddccfa..132c54c626 100644 --- a/samples/portunif/pom.xml +++ b/samples/portunif/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/tls-sni-samples/pom.xml b/samples/tls-sni-samples/pom.xml index e2647260a3..2bb80611bc 100644 --- a/samples/tls-sni-samples/pom.xml +++ b/samples/tls-sni-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.0.payara-p1 + 4.0.2.payara-p2-SNAPSHOT ../../pom.xml From 5f130a236813c837c7a06f4decae72625dddda07 Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Mon, 11 Nov 2024 15:39:53 -0600 Subject: [PATCH 03/16] FISH-9690: adding properties to enable Header Name and Header Value validation against invalid characters RFC-9110 --- .../grizzly/http/HttpCodecFilter.java | 47 +++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java index bc5061c4af..0336c6a10f 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java @@ -22,11 +22,14 @@ import static org.glassfish.grizzly.utils.Charsets.ASCII_CHARSET; import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Pattern; import org.glassfish.grizzly.Buffer; import org.glassfish.grizzly.Connection; import org.glassfish.grizzly.Grizzly; @@ -109,6 +112,16 @@ public abstract class HttpCodecFilter extends HttpBaseFilter implements Monitori * @see #setRemoveHandledContentEncodingHeaders */ private boolean removeHandledContentEncodingHeaders = false; + + private static final String STRICT_HEADER_NAME_VALIDATION_RFC_9110 = "org.glassfish.grizzly.http.STRICT_HEADER_NAME_VALIDATION_RFC_9110"; + + private static final String STRICT_HEADER_VALUE_VALIDATION_RFC_9110 = "org.glassfish.grizzly.http.STRICT_HEADER_VALUE_VALIDATION_RFC_9110"; + + private static final boolean isStrictHeaderNameValidationSet = Boolean.parseBoolean(System.getProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110)); + + private static final boolean isStrictHeaderValueValidationSet = Boolean.parseBoolean(System.getProperty(STRICT_HEADER_VALUE_VALIDATION_RFC_9110)); + + private static final String REGEX_RFC_9110_INVALID_CHARACTERS = "(\\\\n)|(\\\\0)|(\\\\r)|(\\\\x00)|(\\\\x0A)|(\\\\x0D)"; /** * File cache probes @@ -782,7 +795,7 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim b -= Constants.LC_OFFSET; } input[offset] = b; - } else if (b == Constants.CR) { + } else if (isStrictHeaderNameValidationSet && b == Constants.CR) { parsingState.offset = offset - arrayOffs; final int eol = checkEOL(parsingState, input, end); if (eol == 0) { // EOL @@ -794,7 +807,7 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim } } - if (!CookieHeaderParser.isToken(b)) { + if (isStrictHeaderNameValidationSet && !CookieHeaderParser.isToken(b)) { throw new IllegalStateException( "An invalid character 0x" + Integer.toHexString(b) + " was found in the header name"); } @@ -829,6 +842,10 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP parsingState.offset = offset + 1 - arrayOffs; finalizeKnownHeaderValues(httpHeader, parsingState, input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2); parsingState.headerValueStorage.setBytes(input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2); + if (isStrictHeaderValueValidationSet) { + //make validation with regex mode + validateRFC9110Characters(input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2); + } return 0; } } @@ -849,13 +866,37 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP } parsingState.checkpoint2 = parsingState.checkpoint; } - + offset++; } parsingState.offset = offset - arrayOffs; return -1; } + private static void validateRFC9110Characters(final byte[] headerValueContent, int start, int end) { + if (headerValueContent != null) { + if (isInvalidCharacterAvailable(start, end, headerValueContent)) { + throw new IllegalStateException( + "An invalid character NUL, LF or CR found in the header value: " + headerValueContent.toString()); + } + } + } + + /** + * This method evaluates the String from the bytes that contains Header Value and validates if contains literal value + * of \n, \r or \0 , in case any of those characters are available return true + * @param start index of the starting point to extract characters from the byte array + * @param end index of the end point to extract characters from the byte array + * @param bytesFromByteChunk represents the bytes from the request message to be processed + * @return Boolean true if any of those characters are available + */ + private static boolean isInvalidCharacterAvailable(int start, int end, byte[] bytesFromByteChunk) { + byte[] bytesFromHeaderValue = Arrays.copyOfRange(bytesFromByteChunk, start, end); + String uft8String = new String(bytesFromHeaderValue, StandardCharsets.UTF_8); + Pattern pattern = Pattern.compile(REGEX_RFC_9110_INVALID_CHARACTERS); + return pattern.matcher(uft8String).find(); + } + private static void finalizeKnownHeaderNames(final HttpHeader httpHeader, final HeaderParsingState parsingState, final byte[] input, final int start, final int end) { From 6aa29abd90b99c24000b3d0f260424e77dcb9203 Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Mon, 11 Nov 2024 21:53:09 -0600 Subject: [PATCH 04/16] FISH-9690: adding unit test for header value validation --- .../grizzly/http/HttpCodecFilter.java | 4 +- .../grizzly/http/HttpRequestParseTest.java | 39 ++++++++++++++++++- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java index 0336c6a10f..b29c1309cd 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java @@ -113,9 +113,9 @@ public abstract class HttpCodecFilter extends HttpBaseFilter implements Monitori */ private boolean removeHandledContentEncodingHeaders = false; - private static final String STRICT_HEADER_NAME_VALIDATION_RFC_9110 = "org.glassfish.grizzly.http.STRICT_HEADER_NAME_VALIDATION_RFC_9110"; + public static final String STRICT_HEADER_NAME_VALIDATION_RFC_9110 = "org.glassfish.grizzly.http.STRICT_HEADER_NAME_VALIDATION_RFC_9110"; - private static final String STRICT_HEADER_VALUE_VALIDATION_RFC_9110 = "org.glassfish.grizzly.http.STRICT_HEADER_VALUE_VALIDATION_RFC_9110"; + public static final String STRICT_HEADER_VALUE_VALIDATION_RFC_9110 = "org.glassfish.grizzly.http.STRICT_HEADER_VALUE_VALIDATION_RFC_9110"; private static final boolean isStrictHeaderNameValidationSet = Boolean.parseBoolean(System.getProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110)); diff --git a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java index 6d81a74e97..47e1b54189 100644 --- a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java +++ b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java @@ -20,7 +20,6 @@ import java.net.InetSocketAddress; import java.net.SocketAddress; import java.util.Collections; -import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.Future; @@ -50,6 +49,9 @@ import junit.framework.TestCase; +import static org.glassfish.grizzly.http.HttpCodecFilter.STRICT_HEADER_NAME_VALIDATION_RFC_9110; +import static org.glassfish.grizzly.http.HttpCodecFilter.STRICT_HEADER_VALUE_VALIDATION_RFC_9110; + /** * Testing HTTP request parsing * @@ -59,6 +61,20 @@ public class HttpRequestParseTest extends TestCase { public static final int PORT = 19000; + @Override + protected void setUp() throws Exception { + super.setUp(); + System.setProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110, String.valueOf(Boolean.TRUE)); + System.setProperty(STRICT_HEADER_VALUE_VALIDATION_RFC_9110, String.valueOf(Boolean.TRUE)); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + System.setProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110, String.valueOf(Boolean.FALSE)); + System.setProperty(STRICT_HEADER_VALUE_VALIDATION_RFC_9110, String.valueOf(Boolean.FALSE)); + } + public void testCustomMethod() throws Exception { doHttpRequestTest("TAKE", "/index.html", "HTTP/1.0", Collections.>emptyMap(), "\r\n"); } @@ -107,6 +123,27 @@ public void testDisallowedHeaders() { } } + public void testDisallowedCharactersForHeaderContentValues() { + try { + doTestDecoder("GET /index.html HTTP/1.1\nHost: loca\\rlhost\nContent -Length: 1234\n\n", 128); + fail("Bad HTTP headers exception had to be thrown"); + } catch (IllegalStateException e) { + // expected + } + try { + doTestDecoder("GET /index.html HTTP/1.1\nHost: loca\\nlhost\nContent-Length: 1234\n\n", 128); + fail("Bad HTTP headers exception had to be thrown"); + } catch (IllegalStateException e) { + // expected + } + try { + doTestDecoder("GET /index.html HTTP/1.1\nHost: loca\\0lhost\nContent-Length: 1234\n\n", 128); + fail("Bad HTTP headers exception had to be thrown"); + } catch (IllegalStateException e) { + // expected + } + } + public void testIgnoredHeaders() throws Exception { final Map> headers = new HashMap<>(); headers.put("Host", new Pair<>("localhost", "localhost")); From d3e08da62087fea92c7c7a76b33659b802e5cca5 Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Mon, 11 Nov 2024 22:14:43 -0600 Subject: [PATCH 05/16] FISH-9690: adding missed import --- .../java/org/glassfish/grizzly/http/HttpRequestParseTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java index 47e1b54189..af909c529c 100644 --- a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java +++ b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java @@ -24,7 +24,7 @@ import java.util.Map.Entry; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; - +import java.util.HashMap; import org.glassfish.grizzly.Buffer; import org.glassfish.grizzly.Connection; import org.glassfish.grizzly.SocketConnectorHandler; From 3cb27be82beea7ad4a7064f82e90c64e20ee0b22 Mon Sep 17 00:00:00 2001 From: Bongjae Chang Date: Mon, 18 Nov 2024 14:09:20 +0900 Subject: [PATCH 06/16] Issue #2212 Enhances validation of HTTP header names + Added the validation of HTTP header values + Name and value's validation are provided as options. (Improved based on https://github.com/carryel/grizzly/pull/1 @breakponchito) --- .../grizzly/http/HttpCodecFilter.java | 75 ++++++++++--------- .../grizzly/http/util/CookieHeaderParser.java | 9 +++ .../grizzly/http/HttpRequestParseTest.java | 19 +++++ 3 files changed, 67 insertions(+), 36 deletions(-) diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java index b29c1309cd..bc01380bda 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java @@ -22,14 +22,11 @@ import static org.glassfish.grizzly.utils.Charsets.ASCII_CHARSET; import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.regex.Pattern; import org.glassfish.grizzly.Buffer; import org.glassfish.grizzly.Connection; import org.glassfish.grizzly.Grizzly; @@ -120,8 +117,6 @@ public abstract class HttpCodecFilter extends HttpBaseFilter implements Monitori private static final boolean isStrictHeaderNameValidationSet = Boolean.parseBoolean(System.getProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110)); private static final boolean isStrictHeaderValueValidationSet = Boolean.parseBoolean(System.getProperty(STRICT_HEADER_VALUE_VALIDATION_RFC_9110)); - - private static final String REGEX_RFC_9110_INVALID_CHARACTERS = "(\\\\n)|(\\\\0)|(\\\\r)|(\\\\x00)|(\\\\x0A)|(\\\\x0D)"; /** * File cache probes @@ -830,6 +825,20 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP while (offset < limit) { final byte b = input[offset]; if (b == Constants.CR) { + if (isStrictHeaderValueValidationSet) { + if (offset + 1 < limit) { + final byte b2 = input[offset + 1]; + if (b2 == Constants.LF) { + // Continue for next parsing without the validation + offset++; + continue; + } + } else { + // not enough data + parsingState.offset = offset - arrayOffs; + return -1; + } + } } else if (b == Constants.LF) { // Check if it's not multi line header if (offset + 1 < limit) { @@ -842,10 +851,6 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP parsingState.offset = offset + 1 - arrayOffs; finalizeKnownHeaderValues(httpHeader, parsingState, input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2); parsingState.headerValueStorage.setBytes(input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2); - if (isStrictHeaderValueValidationSet) { - //make validation with regex mode - validateRFC9110Characters(input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2); - } return 0; } } @@ -866,35 +871,15 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP } parsingState.checkpoint2 = parsingState.checkpoint; } - - offset++; - } - parsingState.offset = offset - arrayOffs; - return -1; - } - private static void validateRFC9110Characters(final byte[] headerValueContent, int start, int end) { - if (headerValueContent != null) { - if (isInvalidCharacterAvailable(start, end, headerValueContent)) { + if (isStrictHeaderValueValidationSet && !CookieHeaderParser.isText(b)) { throw new IllegalStateException( - "An invalid character NUL, LF or CR found in the header value: " + headerValueContent.toString()); + "An invalid character 0x" + Integer.toHexString(b) + " was found in the header value"); } + offset++; } - } - - /** - * This method evaluates the String from the bytes that contains Header Value and validates if contains literal value - * of \n, \r or \0 , in case any of those characters are available return true - * @param start index of the starting point to extract characters from the byte array - * @param end index of the end point to extract characters from the byte array - * @param bytesFromByteChunk represents the bytes from the request message to be processed - * @return Boolean true if any of those characters are available - */ - private static boolean isInvalidCharacterAvailable(int start, int end, byte[] bytesFromByteChunk) { - byte[] bytesFromHeaderValue = Arrays.copyOfRange(bytesFromByteChunk, start, end); - String uft8String = new String(bytesFromHeaderValue, StandardCharsets.UTF_8); - Pattern pattern = Pattern.compile(REGEX_RFC_9110_INVALID_CHARACTERS); - return pattern.matcher(uft8String).find(); + parsingState.offset = offset - arrayOffs; + return -1; } private static void finalizeKnownHeaderNames(final HttpHeader httpHeader, final HeaderParsingState parsingState, final byte[] input, final int start, @@ -1095,7 +1080,7 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim b -= Constants.LC_OFFSET; } input.put(offset, b); - } else if (b == Constants.CR) { + } else if (isStrictHeaderNameValidationSet && b == Constants.CR) { parsingState.offset = offset; final int eol = checkEOL(parsingState, input); if (eol == 0) { // EOL @@ -1107,7 +1092,7 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim } } - if (!CookieHeaderParser.isToken(b)) { + if (isStrictHeaderNameValidationSet && !CookieHeaderParser.isToken(b)) { throw new IllegalStateException( "An invalid character 0x" + Integer.toHexString(b) + " was found in the header name"); } @@ -1129,6 +1114,20 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP while (offset < limit) { final byte b = input.get(offset); if (b == Constants.CR) { + if (isStrictHeaderValueValidationSet) { + if (offset + 1 < limit) { + final byte b2 = input.get(offset + 1); + if (b2 == Constants.LF) { + // Continue for next parsing without the validation + offset++; + continue; + } + } else { + // not enough data + parsingState.offset = offset; + return -1; + } + } } else if (b == Constants.LF) { // Check if it's not multi line header if (offset + 1 < limit) { @@ -1162,6 +1161,10 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP parsingState.checkpoint2 = parsingState.checkpoint; } + if (isStrictHeaderValueValidationSet && !CookieHeaderParser.isText(b)) { + throw new IllegalStateException( + "An invalid character 0x" + Integer.toHexString(b) + " was found in the header value"); + } offset++; } parsingState.offset = offset; diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/util/CookieHeaderParser.java b/modules/http/src/main/java/org/glassfish/grizzly/http/util/CookieHeaderParser.java index b6ea633b18..1275a06af9 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/util/CookieHeaderParser.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/util/CookieHeaderParser.java @@ -248,6 +248,15 @@ public static boolean isToken(int c) { } } + public static boolean isText(int c) { + // Fast for correct values, slower for incorrect ones + try { + return isText[c]; + } catch (ArrayIndexOutOfBoundsException ex) { + return false; + } + } + /** * Custom implementation that skips many of the safety checks in diff --git a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java index af909c529c..a0fe1ee60d 100644 --- a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java +++ b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java @@ -124,6 +124,15 @@ public void testDisallowedHeaders() { } public void testDisallowedCharactersForHeaderContentValues() { + final StringBuilder sb = new StringBuilder("GET / HTTP/1.1\r\n"); + sb.append("Host: localhost\r\n"); + sb.append("Some-Header: some-"); + // valid header values + sb.append(new char[]{'\t', ' ', '\"', '(', ')', '/', ';', '<', '=', '>', '?', '@', '[', 0x5c, ']', '{', '}'}) + .append("\r\n"); + sb.append("\r\n"); + doTestDecoder(sb.toString(), 128); + try { doTestDecoder("GET /index.html HTTP/1.1\nHost: loca\\rlhost\nContent -Length: 1234\n\n", 128); fail("Bad HTTP headers exception had to be thrown"); @@ -142,6 +151,16 @@ public void testDisallowedCharactersForHeaderContentValues() { } catch (IllegalStateException e) { // expected } + + final char[] invalidChars = new char[]{0x00, 0x01, 0x02, '\r'}; + for (final char ch : invalidChars) { + try { + doTestDecoder("GET /index.html HTTP/1.1\nHost: localhost\nSome-Header: some-" + ch + "value\n\n", 128); + fail("Bad HTTP headers exception had to be thrown"); + } catch (IllegalStateException e) { + // expected + } + } } public void testIgnoredHeaders() throws Exception { From bd81b3629232a1ec0cecb84bcd0a21d1ca4fb6a8 Mon Sep 17 00:00:00 2001 From: Bongjae Chang Date: Tue, 19 Nov 2024 13:49:40 +0900 Subject: [PATCH 07/16] Issue #2212 Enhances validation of HTTP header names + trivial) updated license and re-trigger status checks(https://github.com/eclipse-ee4j/grizzly/pull/2213). --- .../org/glassfish/grizzly/http/util/CookieHeaderParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/util/CookieHeaderParser.java b/modules/http/src/main/java/org/glassfish/grizzly/http/util/CookieHeaderParser.java index 1275a06af9..12e1ce4b7d 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/util/CookieHeaderParser.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/util/CookieHeaderParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2022 Contributors to the Eclipse Foundation + * Copyright (c) 2022, 2024 Contributors to the Eclipse Foundation * Copyright 2004, 2022 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); From c6844b22224d6268b498967a27d23dcf2719f621 Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Fri, 6 Dec 2024 11:40:36 -0600 Subject: [PATCH 08/16] FISH-9690: fix semantic issue on server side --- .../grizzly/http/HttpCodecFilter.java | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java index bc01380bda..d9dcf8213b 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java @@ -716,12 +716,11 @@ protected boolean parseHeaderFromBytes(final HttpHeader httpHeader, final MimeHe parsingState.subState++; } case 1: { // parse header name - final int result = parseHeaderName(httpHeader, mimeHeaders, parsingState, input, end); - if (result == -1) { + if (!parseHeaderName(httpHeader, mimeHeaders, parsingState, input, end)) { return false; - } else if (result == -2) { // EOL. ignore field-lines - parsingState.subState = 0; - parsingState.start = -1; + } + + if(parsingState.subState == 0 && parsingState.start== -1) { return true; } @@ -768,7 +767,7 @@ protected boolean parseHeaderFromBytes(final HttpHeader httpHeader, final MimeHe } } - protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mimeHeaders, final HeaderParsingState parsingState, final byte[] input, + protected boolean parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mimeHeaders, final HeaderParsingState parsingState, final byte[] input, final int end) { final int arrayOffs = parsingState.arrayOffset; @@ -784,7 +783,7 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim parsingState.offset = offset + 1 - arrayOffs; finalizeKnownHeaderNames(httpHeader, parsingState, input, start, offset); - return 0; + return true; } else if (b >= Constants.A && b <= Constants.Z) { if (!preserveHeaderCase) { b -= Constants.LC_OFFSET; @@ -795,7 +794,9 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim final int eol = checkEOL(parsingState, input, end); if (eol == 0) { // EOL // the offset is already increased in the check - return -2; + parsingState.subState = 0; + parsingState.start = -1; + return true; } else if (eol == -2) { // not enough data // by keeping the offset unchanged, we will recheck the EOL at the next opportunity. break; @@ -810,7 +811,7 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim } parsingState.offset = offset - arrayOffs; - return -1; + return false; } protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderParsingState parsingState, final byte[] input, final int end) { @@ -1009,12 +1010,11 @@ protected boolean parseHeaderFromBuffer(final HttpHeader httpHeader, final MimeH parsingState.subState++; } case 1: { // parse header name - final int result = parseHeaderName(httpHeader, mimeHeaders, parsingState, input); - if (result == -1) { + if(!parseHeaderName(httpHeader, mimeHeaders, parsingState, input)){ return false; - } else if (result == -2) { // EOL. ignore field-lines - parsingState.subState = 0; - parsingState.start = -1; + } + + if (parsingState.subState == 0 && parsingState.start == -1) { // EOL. ignore field-lines return true; } @@ -1061,7 +1061,7 @@ protected boolean parseHeaderFromBuffer(final HttpHeader httpHeader, final MimeH } } - protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mimeHeaders, final HeaderParsingState parsingState, final Buffer input) { + protected boolean parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mimeHeaders, final HeaderParsingState parsingState, final Buffer input) { final int limit = Math.min(input.limit(), parsingState.packetLimit); final int start = parsingState.start; int offset = parsingState.offset; @@ -1074,7 +1074,7 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim parsingState.offset = offset + 1; finalizeKnownHeaderNames(httpHeader, parsingState, input, start, offset); - return 0; + return true; } else if (b >= Constants.A && b <= Constants.Z) { if (!preserveHeaderCase) { b -= Constants.LC_OFFSET; @@ -1085,7 +1085,9 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim final int eol = checkEOL(parsingState, input); if (eol == 0) { // EOL // the offset is already increased in the check - return -2; + parsingState.subState = 0; + parsingState.start = -1; + return true; } else if (eol == -2) { // not enough data // by keeping the offset unchanged, we will recheck the EOL at the next opportunity. break; @@ -1100,7 +1102,7 @@ protected int parseHeaderName(final HttpHeader httpHeader, final MimeHeaders mim } parsingState.offset = offset; - return -1; + return false; } protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderParsingState parsingState, final Buffer input) { From dc9208e974ac7b32eb655f1267059400a73e70f3 Mon Sep 17 00:00:00 2001 From: Andrew Pielage Date: Mon, 9 Dec 2024 11:16:09 +0000 Subject: [PATCH 09/16] Add patched-project-release profile --- boms/bom/pom.xml | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/boms/bom/pom.xml b/boms/bom/pom.xml index 65f2ebd4a7..3a2a256292 100644 --- a/boms/bom/pom.xml +++ b/boms/bom/pom.xml @@ -234,4 +234,67 @@ + + + + patched-project-release + + + payara-nexus-artifacts + https://nexus.dev.payara.fish/repository/payara-artifacts/ + + + payara-nexus-snapshots + https://nexus.dev.payara.fish/repository/payara-snapshots/ + + + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + + + --pinentry-mode + loopback + + + + + sign-artifacts + verify + + sign + + + + + + + + From 4f6dafa00dfc3d483d85789a6debe506c524f72d Mon Sep 17 00:00:00 2001 From: Andrew Pielage Date: Mon, 9 Dec 2024 12:01:22 +0000 Subject: [PATCH 10/16] Correct version Signed-off-by: Andrew Pielage --- boms/bom/pom.xml | 2 +- extras/bundles/grizzly-httpservice-bundle/pom.xml | 2 +- extras/bundles/pom.xml | 2 +- extras/connection-pool/pom.xml | 2 +- extras/grizzly-httpservice/pom.xml | 2 +- extras/http-server-jaxws/pom.xml | 2 +- extras/http-server-multipart/pom.xml | 2 +- extras/http-servlet-extras/pom.xml | 2 +- extras/pom.xml | 2 +- extras/tls-sni/pom.xml | 2 +- modules/bundles/comet/pom.xml | 2 +- modules/bundles/core/pom.xml | 2 +- modules/bundles/http-all/pom.xml | 2 +- modules/bundles/http-servlet/pom.xml | 2 +- modules/bundles/http/pom.xml | 2 +- modules/bundles/pom.xml | 2 +- modules/bundles/websockets/pom.xml | 2 +- modules/comet/pom.xml | 2 +- modules/grizzly/pom.xml | 2 +- modules/http-ajp/pom.xml | 2 +- modules/http-server/pom.xml | 2 +- modules/http-servlet/pom.xml | 2 +- modules/http/pom.xml | 2 +- modules/http2/pom.xml | 2 +- modules/monitoring/grizzly/pom.xml | 2 +- modules/monitoring/http-server/pom.xml | 2 +- modules/monitoring/http/pom.xml | 2 +- modules/monitoring/pom.xml | 2 +- modules/pom.xml | 2 +- modules/portunif/pom.xml | 2 +- modules/websockets/pom.xml | 2 +- pom.xml | 4 ++-- samples/connection-pool-samples/pom.xml | 2 +- samples/framework-samples/pom.xml | 2 +- samples/http-ajp-samples/pom.xml | 2 +- samples/http-jaxws-samples/pom.xml | 2 +- samples/http-multipart-samples/pom.xml | 2 +- samples/http-samples/pom.xml | 2 +- samples/http-server-samples/pom.xml | 2 +- samples/pom.xml | 2 +- samples/portunif/pom.xml | 2 +- samples/tls-sni-samples/pom.xml | 2 +- 42 files changed, 43 insertions(+), 43 deletions(-) diff --git a/boms/bom/pom.xml b/boms/bom/pom.xml index 3a2a256292..a1566df96d 100644 --- a/boms/bom/pom.xml +++ b/boms/bom/pom.xml @@ -30,7 +30,7 @@ org.glassfish.grizzly grizzly-bom - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT pom grizzly-bom diff --git a/extras/bundles/grizzly-httpservice-bundle/pom.xml b/extras/bundles/grizzly-httpservice-bundle/pom.xml index 8ff4270e54..83acb05139 100644 --- a/extras/bundles/grizzly-httpservice-bundle/pom.xml +++ b/extras/bundles/grizzly-httpservice-bundle/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/extras/bundles/pom.xml b/extras/bundles/pom.xml index 705af2e88f..91a9b35c77 100644 --- a/extras/bundles/pom.xml +++ b/extras/bundles/pom.xml @@ -23,7 +23,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/connection-pool/pom.xml b/extras/connection-pool/pom.xml index 00402901ef..ebd01097ac 100644 --- a/extras/connection-pool/pom.xml +++ b/extras/connection-pool/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/grizzly-httpservice/pom.xml b/extras/grizzly-httpservice/pom.xml index cc84731c7a..ce138f6ea1 100644 --- a/extras/grizzly-httpservice/pom.xml +++ b/extras/grizzly-httpservice/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/http-server-jaxws/pom.xml b/extras/http-server-jaxws/pom.xml index 9620fed487..8a134fb89d 100644 --- a/extras/http-server-jaxws/pom.xml +++ b/extras/http-server-jaxws/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/http-server-multipart/pom.xml b/extras/http-server-multipart/pom.xml index 4e45c33903..bb201f4cc5 100644 --- a/extras/http-server-multipart/pom.xml +++ b/extras/http-server-multipart/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/http-servlet-extras/pom.xml b/extras/http-servlet-extras/pom.xml index ec56ab1497..bc1d8f5b3c 100644 --- a/extras/http-servlet-extras/pom.xml +++ b/extras/http-servlet-extras/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/extras/pom.xml b/extras/pom.xml index ae6a00a5f3..199c54fc81 100644 --- a/extras/pom.xml +++ b/extras/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../pom.xml diff --git a/extras/tls-sni/pom.xml b/extras/tls-sni/pom.xml index 1d2b370299..df7612e0c8 100644 --- a/extras/tls-sni/pom.xml +++ b/extras/tls-sni/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/bundles/comet/pom.xml b/modules/bundles/comet/pom.xml index 15418670ff..4cb79a630d 100644 --- a/modules/bundles/comet/pom.xml +++ b/modules/bundles/comet/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/bundles/core/pom.xml b/modules/bundles/core/pom.xml index db92c746ff..631030834f 100644 --- a/modules/bundles/core/pom.xml +++ b/modules/bundles/core/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/bundles/http-all/pom.xml b/modules/bundles/http-all/pom.xml index ae301dc318..9ef97f1957 100644 --- a/modules/bundles/http-all/pom.xml +++ b/modules/bundles/http-all/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/bundles/http-servlet/pom.xml b/modules/bundles/http-servlet/pom.xml index c1fab056a0..d8a470601e 100755 --- a/modules/bundles/http-servlet/pom.xml +++ b/modules/bundles/http-servlet/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/bundles/http/pom.xml b/modules/bundles/http/pom.xml index 17f63e7a4e..e9e6e87f14 100755 --- a/modules/bundles/http/pom.xml +++ b/modules/bundles/http/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/bundles/pom.xml b/modules/bundles/pom.xml index c30e27dfe2..67d7142589 100644 --- a/modules/bundles/pom.xml +++ b/modules/bundles/pom.xml @@ -23,7 +23,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/bundles/websockets/pom.xml b/modules/bundles/websockets/pom.xml index 77fc9e31ee..593ca31321 100644 --- a/modules/bundles/websockets/pom.xml +++ b/modules/bundles/websockets/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/comet/pom.xml b/modules/comet/pom.xml index 207040e7ad..d04246569f 100644 --- a/modules/comet/pom.xml +++ b/modules/comet/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/grizzly/pom.xml b/modules/grizzly/pom.xml index bccc0f744e..e4fd749881 100644 --- a/modules/grizzly/pom.xml +++ b/modules/grizzly/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/http-ajp/pom.xml b/modules/http-ajp/pom.xml index ac089cb48e..f7a411b456 100755 --- a/modules/http-ajp/pom.xml +++ b/modules/http-ajp/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/http-server/pom.xml b/modules/http-server/pom.xml index 402e1384df..4dcc3a9d0a 100644 --- a/modules/http-server/pom.xml +++ b/modules/http-server/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/http-servlet/pom.xml b/modules/http-servlet/pom.xml index 58101df9e5..f4c10303ef 100755 --- a/modules/http-servlet/pom.xml +++ b/modules/http-servlet/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/http/pom.xml b/modules/http/pom.xml index f61427ae57..199653db2c 100644 --- a/modules/http/pom.xml +++ b/modules/http/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/http2/pom.xml b/modules/http2/pom.xml index 2e63d9d01b..071d37d631 100644 --- a/modules/http2/pom.xml +++ b/modules/http2/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/monitoring/grizzly/pom.xml b/modules/monitoring/grizzly/pom.xml index 354479b8dc..c9a6d67216 100644 --- a/modules/monitoring/grizzly/pom.xml +++ b/modules/monitoring/grizzly/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/monitoring/http-server/pom.xml b/modules/monitoring/http-server/pom.xml index 894833f9a6..f4000abbee 100644 --- a/modules/monitoring/http-server/pom.xml +++ b/modules/monitoring/http-server/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/monitoring/http/pom.xml b/modules/monitoring/http/pom.xml index 4bcfa5aabc..af8cb8edf2 100644 --- a/modules/monitoring/http/pom.xml +++ b/modules/monitoring/http/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../../pom.xml diff --git a/modules/monitoring/pom.xml b/modules/monitoring/pom.xml index a7276ca071..7d431ba274 100644 --- a/modules/monitoring/pom.xml +++ b/modules/monitoring/pom.xml @@ -23,7 +23,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/pom.xml b/modules/pom.xml index b87d403cae..62ce3c4ef3 100644 --- a/modules/pom.xml +++ b/modules/pom.xml @@ -23,7 +23,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT grizzly-modules diff --git a/modules/portunif/pom.xml b/modules/portunif/pom.xml index 15e447a120..f82cf4a0a3 100644 --- a/modules/portunif/pom.xml +++ b/modules/portunif/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/modules/websockets/pom.xml b/modules/websockets/pom.xml index 3cfa9a45d0..65175570eb 100644 --- a/modules/websockets/pom.xml +++ b/modules/websockets/pom.xml @@ -24,7 +24,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/pom.xml b/pom.xml index 04ecee2ebc..4278a78db5 100644 --- a/pom.xml +++ b/pom.xml @@ -24,12 +24,12 @@ org.glassfish.grizzly grizzly-bom - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT boms/bom/pom.xml grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT pom grizzly-project diff --git a/samples/connection-pool-samples/pom.xml b/samples/connection-pool-samples/pom.xml index 57ef825122..051a4e56d0 100755 --- a/samples/connection-pool-samples/pom.xml +++ b/samples/connection-pool-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/framework-samples/pom.xml b/samples/framework-samples/pom.xml index af9eaaa34e..9756796e48 100755 --- a/samples/framework-samples/pom.xml +++ b/samples/framework-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/http-ajp-samples/pom.xml b/samples/http-ajp-samples/pom.xml index 658354d042..aa7b39303d 100644 --- a/samples/http-ajp-samples/pom.xml +++ b/samples/http-ajp-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/http-jaxws-samples/pom.xml b/samples/http-jaxws-samples/pom.xml index 3b5a6ac83d..64ff85aef2 100644 --- a/samples/http-jaxws-samples/pom.xml +++ b/samples/http-jaxws-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/http-multipart-samples/pom.xml b/samples/http-multipart-samples/pom.xml index 0d7aa98100..7292f6a7bd 100644 --- a/samples/http-multipart-samples/pom.xml +++ b/samples/http-multipart-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/http-samples/pom.xml b/samples/http-samples/pom.xml index ecbe4a33fb..d5ebe6ca76 100755 --- a/samples/http-samples/pom.xml +++ b/samples/http-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/http-server-samples/pom.xml b/samples/http-server-samples/pom.xml index f3a10bc24a..df28f26aa8 100644 --- a/samples/http-server-samples/pom.xml +++ b/samples/http-server-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/pom.xml b/samples/pom.xml index 7336b092c3..26016d7734 100755 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -17,7 +17,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../pom.xml diff --git a/samples/portunif/pom.xml b/samples/portunif/pom.xml index 132c54c626..f5801806f6 100644 --- a/samples/portunif/pom.xml +++ b/samples/portunif/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml diff --git a/samples/tls-sni-samples/pom.xml b/samples/tls-sni-samples/pom.xml index 2bb80611bc..d50926c99b 100644 --- a/samples/tls-sni-samples/pom.xml +++ b/samples/tls-sni-samples/pom.xml @@ -18,7 +18,7 @@ org.glassfish.grizzly grizzly-project - 4.0.2.payara-p2-SNAPSHOT + 4.0.0.payara-p2-SNAPSHOT ../../pom.xml From 9d4bc72f970ea58c15d3ab653e69065ca40e0bb0 Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Mon, 9 Dec 2024 15:50:00 -0600 Subject: [PATCH 11/16] FISH-9690: fixing formatting --- .../main/java/org/glassfish/grizzly/http/HttpCodecFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java index d9dcf8213b..f50af2cafa 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java @@ -719,8 +719,8 @@ protected boolean parseHeaderFromBytes(final HttpHeader httpHeader, final MimeHe if (!parseHeaderName(httpHeader, mimeHeaders, parsingState, input, end)) { return false; } - - if(parsingState.subState == 0 && parsingState.start== -1) { + + if (parsingState.subState == 0 && parsingState.start == -1) { return true; } From 9c57a2c478fff2bc7ed2d50a7c576f0a884a9a94 Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Wed, 11 Dec 2024 12:43:18 -0600 Subject: [PATCH 12/16] FISH-9690: improving code format --- .../java/org/glassfish/grizzly/http/HttpCodecFilter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java index f50af2cafa..c321509a0d 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java @@ -1010,10 +1010,10 @@ protected boolean parseHeaderFromBuffer(final HttpHeader httpHeader, final MimeH parsingState.subState++; } case 1: { // parse header name - if(!parseHeaderName(httpHeader, mimeHeaders, parsingState, input)){ + if (!parseHeaderName(httpHeader, mimeHeaders, parsingState, input)) { return false; - } - + } + if (parsingState.subState == 0 && parsingState.start == -1) { // EOL. ignore field-lines return true; } From 14269311bdd57b3c11e78968c6b215196765f415 Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Wed, 11 Dec 2024 16:32:35 -0600 Subject: [PATCH 13/16] FISH-9690: adding validation to prevent LF character on Header Value content --- .../org/glassfish/grizzly/http/HttpCodecFilter.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java index c321509a0d..4bb728fe42 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java @@ -849,6 +849,11 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP parsingState.offset = offset + 2 - arrayOffs; return -2; } else { + final byte b3 = input[offset - 1]; + if (!(b3 == Constants.CR) && isStrictHeaderValueValidationSet) { + throw new IllegalStateException( + "An invalid character 0x" + Integer.toHexString(b) + " was found in the header value"); + } parsingState.offset = offset + 1 - arrayOffs; finalizeKnownHeaderValues(httpHeader, parsingState, input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2); parsingState.headerValueStorage.setBytes(input, arrayOffs + parsingState.start, arrayOffs + parsingState.checkpoint2); @@ -1139,6 +1144,12 @@ protected static int parseHeaderValue(final HttpHeader httpHeader, final HeaderP parsingState.offset = offset + 2; return -2; } else { + final byte b3 = input.get(offset - 1); + if (!(b3 == Constants.CR) && isStrictHeaderValueValidationSet) { + throw new IllegalStateException( + "An invalid character 0x" + Integer.toHexString(b) + " was found in the header value"); + } + parsingState.offset = offset + 1; finalizeKnownHeaderValues(httpHeader, parsingState, input, parsingState.start, parsingState.checkpoint2); parsingState.headerValueStorage.setBuffer(input, parsingState.start, parsingState.checkpoint2); From 37ec254f8afe2d3de83b23b8665379073ec281cb Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Wed, 11 Dec 2024 18:28:52 -0600 Subject: [PATCH 14/16] FISH-9690: set default value as true --- .../main/java/org/glassfish/grizzly/http/HttpCodecFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java index 4bb728fe42..7342ce5786 100644 --- a/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java +++ b/modules/http/src/main/java/org/glassfish/grizzly/http/HttpCodecFilter.java @@ -114,9 +114,9 @@ public abstract class HttpCodecFilter extends HttpBaseFilter implements Monitori public static final String STRICT_HEADER_VALUE_VALIDATION_RFC_9110 = "org.glassfish.grizzly.http.STRICT_HEADER_VALUE_VALIDATION_RFC_9110"; - private static final boolean isStrictHeaderNameValidationSet = Boolean.parseBoolean(System.getProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110)); + private static final boolean isStrictHeaderNameValidationSet = Boolean.parseBoolean((System.getProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110) == null) ? "true" : System.getProperty(STRICT_HEADER_NAME_VALIDATION_RFC_9110)); - private static final boolean isStrictHeaderValueValidationSet = Boolean.parseBoolean(System.getProperty(STRICT_HEADER_VALUE_VALIDATION_RFC_9110)); + private static final boolean isStrictHeaderValueValidationSet = Boolean.parseBoolean((System.getProperty(STRICT_HEADER_VALUE_VALIDATION_RFC_9110) == null) ? "true": System.getProperty(STRICT_HEADER_VALUE_VALIDATION_RFC_9110)); /** * File cache probes From 1dfcbd0c199c7c9c526562eff613995243d06027 Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Thu, 12 Dec 2024 10:14:12 -0600 Subject: [PATCH 15/16] FISH-9690: fixing failures on unit tests --- .../grizzly/http/ChunkedTransferEncodingTest.java | 2 +- .../glassfish/grizzly/http/HttpRequestParseTest.java | 12 ++++++------ .../grizzly/http/HttpResponseParseTest.java | 2 +- .../glassfish/grizzly/http/HttpSemanticsTest.java | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/http/src/test/java/org/glassfish/grizzly/http/ChunkedTransferEncodingTest.java b/modules/http/src/test/java/org/glassfish/grizzly/http/ChunkedTransferEncodingTest.java index 844e44e1bd..2daf75e00d 100644 --- a/modules/http/src/test/java/org/glassfish/grizzly/http/ChunkedTransferEncodingTest.java +++ b/modules/http/src/test/java/org/glassfish/grizzly/http/ChunkedTransferEncodingTest.java @@ -151,7 +151,7 @@ public void after() throws Exception { } public ChunkedTransferEncodingTest(String eol, boolean isChunkWhenParsing) { - this.eol = eol; + this.eol = "\r\n"; this.isChunkWhenParsing = isChunkWhenParsing; } diff --git a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java index a0fe1ee60d..d516b17650 100644 --- a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java +++ b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpRequestParseTest.java @@ -184,9 +184,9 @@ public void testMultiLineHeaders() throws Exception { public void testHeadersN() throws Exception { Map> headers = new HashMap<>(); headers.put("Host", new Pair<>("localhost", "localhost")); - headers.put("Multi-line", new Pair<>("first\r\n second\n third", "first second third")); + headers.put("Multi-line", new Pair<>("first\r\n second\r\n third", "first second third")); headers.put("Content-length", new Pair<>("2345", "2345")); - doHttpRequestTest("POST", "/index.html", "HTTP/1.1", headers, "\n"); + doHttpRequestTest("POST", "/index.html", "HTTP/1.1", headers, "\r\n"); } public void testCompleteURI() throws Exception { @@ -194,7 +194,7 @@ public void testCompleteURI() throws Exception { headers.put("Host", new Pair(null, "localhost:8180")); headers.put("Content-length", new Pair<>("2345", "2345")); doHttpRequestTest(new Pair<>("POST", "POST"), new Pair<>("http://localhost:8180/index.html", "/index.html"), - new Pair<>("HTTP/1.1", "HTTP/1.1"), headers, "\n", false); + new Pair<>("HTTP/1.1", "HTTP/1.1"), headers, "\r\n", false); } public void testCompleteEmptyURI() throws Exception { @@ -202,7 +202,7 @@ public void testCompleteEmptyURI() throws Exception { headers.put("Host", new Pair(null, "localhost:8180")); headers.put("Content-length", new Pair<>("2345", "2345")); doHttpRequestTest(new Pair<>("POST", "POST"), new Pair<>("http://localhost:8180", "/"), - new Pair<>("HTTP/1.1", "HTTP/1.1"), headers, "\n", false); + new Pair<>("HTTP/1.1", "HTTP/1.1"), headers, "\r\n", false); } public void testDecoderOK() { @@ -246,7 +246,7 @@ public void testDecoderOverflowHeader1() { } public void testDecoderOverflowHeader2() { - doTestDecoder("GET /index.html HTTP/1.0\nHost: localhost\n\n", 42); + doTestDecoder("GET /index.html HTTP/1.0\r\nHost: localhost\r\n\r\n", 50); } public void testDecoderOverflowHeader3() { @@ -263,7 +263,7 @@ public void testDecoderOverflowHeader4() { } public void testChunkedTransferEncodingCaseInsensitive() { - HttpPacket packet = doTestDecoder("POST /index.html HTTP/1.1\nHost: localhost\nTransfer-Encoding: CHUNked\r\n\r\n0\r\n\r\n", 4096); + HttpPacket packet = doTestDecoder("POST /index.html HTTP/1.1\r\nHost: localhost\r\nTransfer-Encoding: CHUNked\r\n\r\n0\r\n\r\n", 4096); assertTrue(packet.getHttpHeader().isChunked()); } diff --git a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpResponseParseTest.java b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpResponseParseTest.java index 250d3836a7..90f36c2a97 100644 --- a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpResponseParseTest.java +++ b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpResponseParseTest.java @@ -84,7 +84,7 @@ public void testHeadersN() throws Exception { headers.put("Header1", new Pair<>("localhost", "localhost")); headers.put("Multi-line", new Pair<>("first\n second\n third", "first seconds third")); headers.put("Content-length", new Pair<>("2345", "2345")); - doHttpResponseTest("HTTP/1.0", 200, "DONE", headers, "\n"); + doHttpResponseTest("HTTP/1.0", 200, "DONE", headers, "\r\n"); } public void testDecoder100continueThen200() { diff --git a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpSemanticsTest.java b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpSemanticsTest.java index 8e3e4c934d..f20e0c6c3a 100644 --- a/modules/http/src/test/java/org/glassfish/grizzly/http/HttpSemanticsTest.java +++ b/modules/http/src/test/java/org/glassfish/grizzly/http/HttpSemanticsTest.java @@ -677,7 +677,7 @@ public void testHttpHeadersLimit() throws Throwable { public void testExplicitConnectionCloseHeader() throws Throwable { final TCPNIOConnection connection = new TCPNIOConnection(TCPNIOTransportBuilder.newInstance().build(), null); - Buffer requestBuf = Buffers.wrap(connection.getMemoryManager(), "GET /path HTTP/1.1\n" + "Host: localhost:" + PORT + '\n' + '\n'); + Buffer requestBuf = Buffers.wrap(connection.getMemoryManager(), "GET /path HTTP/1.1\r\n" + "Host: localhost:" + PORT + "\r\n" + "\r\n"); FilterChainContext ctx = FilterChainContext.create(connection); ctx.setMessage(requestBuf); From ca7168a476be7a588fe3bc8f63be0e8a6454b7c2 Mon Sep 17 00:00:00 2001 From: Alfonso Altamirano Date: Thu, 12 Dec 2024 12:16:50 -0600 Subject: [PATCH 16/16] FISH-9690: more fixes on unit tests --- .../org/glassfish/grizzly/comet/BasicCometTest.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/comet/src/test/java/org/glassfish/grizzly/comet/BasicCometTest.java b/modules/comet/src/test/java/org/glassfish/grizzly/comet/BasicCometTest.java index 0eb262e277..bd39a01dfa 100644 --- a/modules/comet/src/test/java/org/glassfish/grizzly/comet/BasicCometTest.java +++ b/modules/comet/src/test/java/org/glassfish/grizzly/comet/BasicCometTest.java @@ -105,7 +105,7 @@ public void testClientCloseConnection() throws Exception { s.setSoLinger(false, 0); s.setSoTimeout(500); OutputStream os = s.getOutputStream(); - String a = "GET " + alias + " HTTP/1.1\n" + "Host: localhost:" + PORT + "\n\n"; + String a = "GET " + alias + " HTTP/1.1\r\n" + "Host: localhost:" + PORT + "\r\n\r\n"; System.out.println(" " + a); os.write(a.getBytes()); os.flush(); @@ -167,10 +167,10 @@ public void service(Request request, Response response) throws Exception { Socket s = new Socket("localhost", PORT); s.setSoTimeout(10 * 1000); OutputStream os = s.getOutputStream(); - String cometRequest = "GET " + alias + " HTTP/1.1\nHost: localhost:" + PORT + "\n\n"; - String staticRequest = "GET /static HTTP/1.1\nHost: localhost:" + PORT + "\n\n"; + String cometRequest = "GET " + alias + " HTTP/1.1\r\nHost: localhost:" + PORT + "\r\n\r\n"; + String staticRequest = "GET /static HTTP/1.1\r\nHost: localhost:" + PORT + "\r\n\r\n"; - String lastCometRequest = "GET " + alias + " HTTP/1.1\n" + "Host: localhost:" + PORT + "\nConnection: close\n\n"; + String lastCometRequest = "GET " + alias + " HTTP/1.1\r\n" + "Host: localhost:" + PORT + "\r\nConnection: close\r\n\r\n"; String pipelinedRequest1 = cometRequest + staticRequest + cometRequest; String pipelinedRequest2 = cometRequest + staticRequest + lastCometRequest; @@ -256,8 +256,8 @@ public void service(Request request, Response response) throws Exception { Socket s = new Socket("localhost", PORT); s.setSoTimeout(10 * 1000); OutputStream os = s.getOutputStream(); - String cometRequest = "GET " + alias + " HTTP/1.1\nHost: localhost:" + PORT + "\n\n"; - String staticRequest = "GET /static HTTP/1.1\nHost: localhost:" + PORT + "\n\n"; + String cometRequest = "GET " + alias + " HTTP/1.1\r\nHost: localhost:" + PORT + "\r\n\r\n"; + String staticRequest = "GET /static HTTP/1.1\r\nHost: localhost:" + PORT + "\r\n\r\n"; try { os.write(cometRequest.getBytes());