From 6d583c7d8cc41a188a190218a6489541b79cf35a Mon Sep 17 00:00:00 2001 From: Karl Wright Date: Thu, 22 Jun 2017 09:51:27 -0400 Subject: [PATCH] HTTPCLIENT-1859: Encode header name, filename appropriately --- .../http/entity/mime/FormBodyPartBuilder.java | 19 ++++++++++++-- .../entity/mime/TestFormBodyPartBuilder.java | 25 +++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/httpmime/src/main/java/org/apache/http/entity/mime/FormBodyPartBuilder.java b/httpmime/src/main/java/org/apache/http/entity/mime/FormBodyPartBuilder.java index a04d9d6bc..31c203a17 100644 --- a/httpmime/src/main/java/org/apache/http/entity/mime/FormBodyPartBuilder.java +++ b/httpmime/src/main/java/org/apache/http/entity/mime/FormBodyPartBuilder.java @@ -103,11 +103,11 @@ public class FormBodyPartBuilder { if (headerCopy.getField(MIME.CONTENT_DISPOSITION) == null) { final StringBuilder buffer = new StringBuilder(); buffer.append("form-data; name=\""); - buffer.append(this.name); + buffer.append(encodeForHeader(this.name)); buffer.append("\""); if (this.body.getFilename() != null) { buffer.append("; filename=\""); - buffer.append(this.body.getFilename()); + buffer.append(encodeForHeader(this.body.getFilename())); buffer.append("\""); } headerCopy.addField(new MinimalField(MIME.CONTENT_DISPOSITION, buffer.toString())); @@ -138,4 +138,19 @@ public class FormBodyPartBuilder { return new FormBodyPart(this.name, this.body, headerCopy); } + private static String encodeForHeader(final String headerName) { + if (headerName == null) { + return null; + } + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < headerName.length(); i++) { + final char x = headerName.charAt(i); + if (x == '"' || x == '\\' || x == '\r') { + sb.append("\\"); + } + sb.append(x); + } + return sb.toString(); + } + } diff --git a/httpmime/src/test/java/org/apache/http/entity/mime/TestFormBodyPartBuilder.java b/httpmime/src/test/java/org/apache/http/entity/mime/TestFormBodyPartBuilder.java index 49a6bd81e..56dd4f9b8 100644 --- a/httpmime/src/test/java/org/apache/http/entity/mime/TestFormBodyPartBuilder.java +++ b/httpmime/src/test/java/org/apache/http/entity/mime/TestFormBodyPartBuilder.java @@ -27,12 +27,14 @@ package org.apache.http.entity.mime; +import java.io.ByteArrayInputStream; import java.io.File; import java.util.Arrays; import java.util.List; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.entity.mime.content.InputStreamBody; import org.apache.http.entity.mime.content.StringBody; import org.junit.Assert; import org.junit.Test; @@ -58,6 +60,29 @@ public class TestFormBodyPartBuilder { header.getFields()); } + @Test + public void testCharacterStuffing() throws Exception { + final FormBodyPartBuilder builder = FormBodyPartBuilder.create(); + final InputStreamBody fileBody = new InputStreamBody(new ByteArrayInputStream( + "hello world".getBytes("UTF-8")), "stuff_with \"quotes\" and \\slashes\\.bin"); + final FormBodyPart bodyPart2 = builder + .setName("yada_with \"quotes\" and \\slashes\\") + .setBody(fileBody) + .build(); + + Assert.assertNotNull(bodyPart2); + Assert.assertEquals("yada_with \"quotes\" and \\slashes\\", bodyPart2.getName()); + Assert.assertEquals(fileBody, bodyPart2.getBody()); + final Header header2 = bodyPart2.getHeader(); + Assert.assertNotNull(header2); + assertFields(Arrays.asList( + new MinimalField("Content-Disposition", "form-data; name=\"yada_with \\\"quotes\\\" " + + "and \\\\slashes\\\\\"; filename=\"stuff_with \\\"quotes\\\" and \\\\slashes\\\\.bin\""), + new MinimalField("Content-Type", "application/octet-stream"), + new MinimalField("Content-Transfer-Encoding", "binary")), + header2.getFields()); + } + @Test public void testBuildBodyPartMultipleBuilds() throws Exception { final StringBody stringBody = new StringBody("stuff", ContentType.TEXT_PLAIN);