diff --git a/connectors/jdk-connector/pom.xml b/connectors/jdk-connector/pom.xml index bc24148e54..2d4b269303 100644 --- a/connectors/jdk-connector/pom.xml +++ b/connectors/jdk-connector/pom.xml @@ -1,7 +1,7 @@ <?xml version="1.0"?> <!-- - Copyright (c) 2011, 2023 Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011, 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 @@ -98,6 +98,7 @@ <reuseForks>false</reuseForks> <excludes> <exclude>**/SslFilterTLS13Test.java</exclude> + <exclude>**/SslFilterTLS13UrlStoresTest.java</exclude> </excludes> </configuration> </plugin> diff --git a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/ContentDisposition.java b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/ContentDisposition.java index 34188e7382..6d77453aa3 100644 --- a/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/ContentDisposition.java +++ b/media/multipart/src/main/java/org/glassfish/jersey/media/multipart/ContentDisposition.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2023 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 @@ -28,8 +28,6 @@ import org.glassfish.jersey.message.internal.HttpHeaderReader; import org.glassfish.jersey.uri.UriComponent; -import javax.ws.rs.core.HttpHeaders; - /** * A content disposition header. * @@ -60,10 +58,13 @@ public class ContentDisposition { private static final Pattern FILENAME_VALUE_CHARS_PATTERN = Pattern.compile("(%[a-f0-9]{2}|[a-z0-9!#$&+.^_`|~-])+", Pattern.CASE_INSENSITIVE); + private static final char QUOTE = '"'; + private static final char BACK_SLASH = '\\'; + protected ContentDisposition(final String type, final String fileName, final Date creationDate, final Date modificationDate, final Date readDate, final long size) { this.type = type; - this.fileName = fileName; + this.fileName = encodeAsciiFileName(fileName); this.creationDate = creationDate; this.modificationDate = modificationDate; this.readDate = readDate; @@ -211,6 +212,23 @@ protected void addLongParameter(final StringBuilder sb, final String name, final } } + protected String encodeAsciiFileName(String fileName) { + if (fileName == null + || (fileName.indexOf(QUOTE) == -1 + && fileName.indexOf(BACK_SLASH) == -1)) { + return fileName; + } + final char[] chars = fileName.toCharArray(); + final StringBuilder encodedBuffer = new StringBuilder(); + for (char c : chars) { + if (c == QUOTE || c == BACK_SLASH) { + encodedBuffer.append(BACK_SLASH); + } + encodedBuffer.append(c); + } + return encodedBuffer.toString(); + } + private void createParameters() throws ParseException { defineFileName(); @@ -229,7 +247,7 @@ private void defineFileName() throws ParseException { final String fileNameExt = parameters.get("filename*"); if (fileNameExt == null) { - this.fileName = fileName; + this.fileName = encodeAsciiFileName(fileName); return; } diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/ContentDispositionTest.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/ContentDispositionTest.java index c4bcd53d21..8cecb6b1c1 100644 --- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/ContentDispositionTest.java +++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/api/ContentDispositionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -88,6 +88,14 @@ public void testCreate() { } } + @Test + void testContentDispositionEncoded() { + final Date date = new Date(); + final ContentDisposition contentDisposition = ContentDisposition.type(contentDispositionType).fileName("\"rm\\ -rf\".sh") + .creationDate(date).modificationDate(date).readDate(date).size(312).build(); + assertEquals("\\\"rm\\\\ -rf\\\".sh", contentDisposition.getFileName()); + } + @Test public void testToString() { final Date date = new Date();