Repository: olingo-odata2 Updated Branches: refs/heads/master 8b6b25733 -> 0689384db
[OLINGO-1016] Fix allowed characters in batch header names Project: http://git-wip-us.apache.org/repos/asf/olingo-odata2/repo Commit: http://git-wip-us.apache.org/repos/asf/olingo-odata2/commit/0689384d Tree: http://git-wip-us.apache.org/repos/asf/olingo-odata2/tree/0689384d Diff: http://git-wip-us.apache.org/repos/asf/olingo-odata2/diff/0689384d Branch: refs/heads/master Commit: 0689384db6f11f888faf09d150adb60e654eb6e4 Parents: 8b6b257 Author: mibo <[email protected]> Authored: Tue Aug 30 20:58:46 2016 +0200 Committer: mibo <[email protected]> Committed: Tue Aug 30 20:58:46 2016 +0200 ---------------------------------------------------------------------- .../odata2/core/batch/v2/BatchParserCommon.java | 37 ++++++++++++++------ .../core/batch/v2/BatchParserCommonTest.java | 29 ++++++++++++--- 2 files changed, 51 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/0689384d/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java index 47b169c..76b44ce 100644 --- a/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java +++ b/odata2-lib/odata-core/src/main/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommon.java @@ -42,15 +42,32 @@ public class BatchParserCommon { private static final Pattern PATTERN_LAST_CRLF = Pattern.compile("(.*)(\r\n){1}( *)", Pattern.DOTALL); - private static final String REG_EX_BOUNDARY = - "([a-zA-Z0-9_\\-\\.'\\+]{1,70})|\"([a-zA-Z0-9_\\-\\.'\\+\\s\\" + - "(\\),/:=\\?]{1,69}[a-zA-Z0-9_\\-\\.'\\+\\(\\),/:=\\?])\""; // See RFC 2046 - - public static final Pattern PATTERN_MULTIPART_MIXED = Pattern - .compile("multipart/mixed(.*)", Pattern.CASE_INSENSITIVE); - final static String REG_EX_APPLICATION_HTTP = "application/http"; - public static final Pattern PATTERN_HEADER_LINE = Pattern.compile("([a-zA-Z\\-]+):\\s?(.*)\\s*"); - public static final Pattern PATTERN_CONTENT_TYPE_APPLICATION_HTTP = Pattern.compile(REG_EX_APPLICATION_HTTP, + // Multipart boundaries are defined in RFC 2046: + // boundary := 0*69<bchars> bcharsnospace + // bchars := bcharsnospace / " " + // bcharsnospace := DIGIT / ALPHA / "'" / "(" / ")" / "+" / "_" / "," / "-" / "." / "/" / ":" / "=" / "?" + // The first alternative is for the case that only characters are used that don't need quoting. + private static final Pattern PATTERN_BOUNDARY = Pattern.compile( + "((?:\\w|[-.'+]){1,70})|" + + "\"((?:\\w|[-.'+(),/:=?]|\\s){0,69}(?:\\w|[-.'+(),/:=?]))\""); + + // HTTP header fields are defined in RFC 7230: + // header-field = field-name ":" OWS field-value OWS + // field-name = token + // field-value = *( field-content / obs-fold ) + // field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] + // field-vchar = VCHAR / obs-text + // obs-fold = CRLF 1*( SP / HTAB ) + // token = 1*tchar + // tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" + // / DIGIT / ALPHA + // For the field-name the specification is followed strictly, + // but for the field-value the pattern currently accepts more than specified. + protected static final Pattern PATTERN_HEADER_LINE = Pattern.compile("((?:\\w|[!#$%\\&'*+\\-.^`|~])+):\\s?(.*)\\s*"); + + public static final Pattern PATTERN_MULTIPART_MIXED = Pattern.compile("multipart/mixed(.*)", + Pattern.CASE_INSENSITIVE); + public static final Pattern PATTERN_CONTENT_TYPE_APPLICATION_HTTP = Pattern.compile("application/http", Pattern.CASE_INSENSITIVE); public static final Pattern PATTERN_RELATIVE_URI = Pattern.compile("([^/][^?]*)(\\?.*)?"); @@ -226,7 +243,7 @@ public class BatchParserCommon { final String[] attrValue = pair.split("="); if (attrValue.length == 2 && "boundary".equals(attrValue[0].trim().toLowerCase(Locale.ENGLISH))) { - if (attrValue[1].matches(REG_EX_BOUNDARY)) { + if (PATTERN_BOUNDARY.matcher(attrValue[1]).matches()) { return trimQuota(attrValue[1].trim()); } else { throw new BatchException(BatchException.INVALID_BOUNDARY.addContent(line)); http://git-wip-us.apache.org/repos/asf/olingo-odata2/blob/0689384d/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommonTest.java ---------------------------------------------------------------------- diff --git a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommonTest.java b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommonTest.java index 95d7dc5..dc5b63c 100644 --- a/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommonTest.java +++ b/odata2-lib/odata-core/src/test/java/org/apache/olingo/odata2/core/batch/v2/BatchParserCommonTest.java @@ -18,7 +18,9 @@ ******************************************************************************/ package org.apache.olingo.odata2.core.batch.v2; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import java.util.ArrayList; import java.util.List; @@ -26,9 +28,6 @@ import java.util.List; import org.apache.olingo.odata2.api.batch.BatchException; import org.apache.olingo.odata2.api.commons.HttpHeaders; import org.apache.olingo.odata2.core.batch.BatchHelper; -import org.apache.olingo.odata2.core.batch.v2.BatchParserCommon; -import org.apache.olingo.odata2.core.batch.v2.Header; -import org.apache.olingo.odata2.core.batch.v2.Line; import org.junit.Test; public class BatchParserCommonTest { @@ -169,7 +168,27 @@ public class BatchParserCommonTest { assertNotNull(acceptLanguageHeader); assertEquals(3, acceptLanguageHeader.size()); } - + + @Test + public void headersWithSpecialNames() throws Exception { + final Header header = BatchParserCommon.consumeHeaders(toLineList(new String[] { + "Test0123456789: 42" + CRLF, + "a_b: c/d" + CRLF, + "!#$%&'*+-.^_`|~: weird" + CRLF })); + assertNotNull(header); + assertEquals("42", header.getHeader("Test0123456789")); + assertEquals("c/d", header.getHeader("a_b")); + assertEquals("weird", header.getHeader("!#$%&'*+-.^_`|~")); + } + + @Test + public void headerWithWrongName() throws Exception { + final Header header = BatchParserCommon.consumeHeaders(toLineList(new String[] { + "a,b: c/d" + CRLF })); + assertNotNull(header); + assertNull(header.getHeader("a,b")); + } + @Test public void testRemoveEndingCRLF() { String line = "Test\r\n";
