Author: markt Date: Wed May 30 15:38:35 2018 New Revision: 1832554 URL: http://svn.apache.org/viewvc?rev=1832554&view=rev Log: Correctly handle an invalid quality value in an Accept-Language header. Expand unit tests to cover this issue and improve coverage.
Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAcceptLanguage.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java?rev=1832554&r1=1832553&r2=1832554&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java Wed May 30 15:38:35 2018 @@ -580,35 +580,43 @@ public class HttpParser { // Should be no more than 3 decimal places StringBuilder value = new StringBuilder(5); - int decimalPlacesRead = 0; + int decimalPlacesRead = -1; + if (c == '0' || c == '1') { value.append((char) c); c = input.read(); - if (c == '.') { - value.append('.'); - } else if (c < '0' || c > '9') { - decimalPlacesRead = 3; - } + while (true) { - c = input.read(); - if (c >= '0' && c <= '9') { + if (decimalPlacesRead == -1 && c == '.') { + value.append('.'); + decimalPlacesRead = 0; + } else if (decimalPlacesRead > -1 && c >= '0' && c <= '9') { if (decimalPlacesRead < 3) { value.append((char) c); decimalPlacesRead++; } - } else if (c == delimiter || c == 9 || c == 32 || c == -1) { - break; } else { - // Malformed. Use quality of zero so it is dropped and skip until - // EOF or the next delimiter - skipUntil(input, c, delimiter); - return 0; + break; } + c = input.read(); } } else { // Malformed. Use quality of zero so it is dropped and skip until // EOF or the next delimiter skipUntil(input, c, delimiter); + return 0; + } + + if (c == 9 || c == 32) { + skipLws(input); + c = input.read(); + } + + // Must be at delimiter or EOF + if (c != delimiter && c != -1) { + // Malformed. Use quality of zero so it is dropped and skip until + // EOF or the next delimiter + skipUntil(input, c, delimiter); return 0; } Modified: tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAcceptLanguage.java URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAcceptLanguage.java?rev=1832554&r1=1832553&r2=1832554&view=diff ============================================================================== --- tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAcceptLanguage.java (original) +++ tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAcceptLanguage.java Wed May 30 15:38:35 2018 @@ -115,6 +115,33 @@ public class TestAcceptLanguage { @Test public void testSingle10() throws Exception { + List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb; q =\t1")); + + Assert.assertEquals(1, actual.size()); + Assert.assertEquals(L_EN_GB, actual.get(0).getLocale()); + Assert.assertEquals(Q1_000, actual.get(0).getQuality(), 0.0001); + } + + @Test + public void testSingle11() throws Exception { + List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb; q =1\t")); + + Assert.assertEquals(1, actual.size()); + Assert.assertEquals(L_EN_GB, actual.get(0).getLocale()); + Assert.assertEquals(Q1_000, actual.get(0).getQuality(), 0.0001); + } + + @Test + public void testSingle12() throws Exception { + List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb; q =\t1\t")); + + Assert.assertEquals(1, actual.size()); + Assert.assertEquals(L_EN_GB, actual.get(0).getLocale()); + Assert.assertEquals(Q1_000, actual.get(0).getQuality(), 0.0001); + } + + @Test + public void testSingle13() throws Exception { List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb;q=0.5")); Assert.assertEquals(1, actual.size()); @@ -123,7 +150,7 @@ public class TestAcceptLanguage { } @Test - public void testSingle11() throws Exception { + public void testSingle14() throws Exception { List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb;q=0.50")); Assert.assertEquals(1, actual.size()); @@ -132,7 +159,7 @@ public class TestAcceptLanguage { } @Test - public void testSingle12() throws Exception { + public void testSingle15() throws Exception { List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb;q=0.500")); Assert.assertEquals(1, actual.size()); @@ -141,7 +168,7 @@ public class TestAcceptLanguage { } @Test - public void testSingle13() throws Exception { + public void testSingle16() throws Exception { List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb;q=0.5009")); Assert.assertEquals(1, actual.size()); @@ -149,6 +176,16 @@ public class TestAcceptLanguage { Assert.assertEquals(Q0_500, actual.get(0).getQuality(), 0.0001); } + @Test + public void testSingle17() throws Exception { + List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb;,")); + + Assert.assertEquals(1, actual.size()); + Assert.assertEquals(L_EN_GB, actual.get(0).getLocale()); + Assert.assertEquals(Q1_000, actual.get(0).getQuality(), 0.0001); + } + + @Test public void testMalformed01() throws Exception { @@ -231,6 +268,50 @@ public class TestAcceptLanguage { Assert.assertEquals(Q1_000, actual.get(0).getQuality(), 0.0001); } + @Test + public void testMalformed10() throws Exception { + List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en;q")); + + Assert.assertEquals(0, actual.size()); + } + + @Test + public void testMalformed11() throws Exception { + List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb;q=1a0")); + + Assert.assertEquals(0, actual.size()); + } + + @Test + public void testMalformed12() throws Exception { + List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb;q=1.a0")); + + Assert.assertEquals(0, actual.size()); + } + + @Test + public void testMalformed13() throws Exception { + List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb;q=1.0a0")); + + Assert.assertEquals(0, actual.size()); + } + + @Test + public void testMalformed14() throws Exception { + List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb;q=1.1")); + + Assert.assertEquals(0, actual.size()); + } + + @Test + public void testMalformed15() throws Exception { + List<AcceptLanguage> actual = AcceptLanguage.parse(new StringReader("en-gb;q=1a0,en-gb;q=0.5")); + + Assert.assertEquals(1, actual.size()); + Assert.assertEquals(L_EN_GB, actual.get(0).getLocale()); + Assert.assertEquals(Q0_500, actual.get(0).getQuality(), 0.0001); + } + @Test public void testMultiple01() throws Exception { Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1832554&r1=1832553&r2=1832554&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Wed May 30 15:38:35 2018 @@ -169,6 +169,10 @@ Correctly handle a digest authorization header when one of the hex field values ends the header with in an invalid character. (markt) </fix> + <fix> + Correctly handle an invalid quality value in an + <code>Accept-Language</code> header. (markt) + </fix> </changelog> </subsection> <subsection name="Jasper"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org