You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2014/03/18 11:27:31 UTC

svn commit: r1578812 - in /tomcat/trunk: java/org/apache/tomcat/util/buf/Ascii.java test/org/apache/tomcat/util/buf/TestAscii.java webapps/docs/changelog.xml

Author: markt
Date: Tue Mar 18 10:27:31 2014
New Revision: 1578812

URL: http://svn.apache.org/r1578812
Log:
Fix possible overflow when parsing long values from a byte array.

Added:
    tomcat/trunk/test/org/apache/tomcat/util/buf/TestAscii.java
Modified:
    tomcat/trunk/java/org/apache/tomcat/util/buf/Ascii.java
    tomcat/trunk/webapps/docs/changelog.xml

Modified: tomcat/trunk/java/org/apache/tomcat/util/buf/Ascii.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/buf/Ascii.java?rev=1578812&r1=1578811&r2=1578812&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/buf/Ascii.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/buf/Ascii.java Tue Mar 18 10:27:31 2014
@@ -33,10 +33,11 @@ public final class Ascii {
      */
     private static final boolean[] isDigit = new boolean[256];
 
+    private static final long OVERFLOW_LIMIT = Long.MAX_VALUE / 10;
+
     /*
      * Initialize character translation and type tables.
      */
-
     static {
         for (int i = 0; i < 256; i++) {
             toLower[i] = (byte)i;
@@ -85,19 +86,12 @@ public final class Ascii {
         }
 
         long n = c - '0';
-        long m;
-
         while (--len > 0) {
-            if (!isDigit(c = b[off++])) {
-                throw new NumberFormatException();
-            }
-            m = n * 10 + c - '0';
-
-            if (m < n) {
-                // Overflow
-                throw new NumberFormatException();
+            if (isDigit(c = b[off++]) &&
+                    (n < OVERFLOW_LIMIT || (n == OVERFLOW_LIMIT && (c - '0') < 8))) {
+                n = n * 10 + c - '0';
             } else {
-                n = m;
+                throw new NumberFormatException();
             }
         }
 

Added: tomcat/trunk/test/org/apache/tomcat/util/buf/TestAscii.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/buf/TestAscii.java?rev=1578812&view=auto
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/buf/TestAscii.java (added)
+++ tomcat/trunk/test/org/apache/tomcat/util/buf/TestAscii.java Tue Mar 18 10:27:31 2014
@@ -0,0 +1,65 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package org.apache.tomcat.util.buf;
+
+import java.math.BigInteger;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+public class TestAscii {
+
+    @Test
+    public void testParseLong1() {
+        String value = "9223372036854775807"; // Long.MAX_VALUE
+        byte[] bytes = value.getBytes();
+        long result = Ascii.parseLong(bytes, 0, bytes.length);
+        Assert.assertEquals(value, String.valueOf(result));
+    }
+
+    @Test(expected = NumberFormatException.class)
+    public void testParseLong2() {
+        byte[] bytes = "9223372036854775808".getBytes(); // Long.MAX_VALUE + 1
+        long result = Ascii.parseLong(bytes, 0, bytes.length);
+        Assert.fail("NumberFormatException expected, got: " + result);
+    }
+
+    @Test(expected = NumberFormatException.class)
+    public void testParseLong3() {
+        byte[] bytes = "9223372036854775810".getBytes(); // Long.MAX_VALUE + 3
+        long result = Ascii.parseLong(bytes, 0, bytes.length);
+        Assert.fail("NumberFormatException expected, got: " + result);
+    }
+
+    @Test(expected = NumberFormatException.class)
+    public void testParseLong4() {
+        BigInteger x = BigInteger.valueOf(5000000000L).shiftLeft(32);
+        byte[] bytes = String.valueOf(x).getBytes();
+        long result = Ascii.parseLong(bytes, 0, bytes.length);
+        Assert.fail("NumberFormatException expected, got: " + result);
+    }
+
+    @Test
+    public void testParseLong5() {
+        String value = "9223372036854775806"; // Long.MAX_VALUE - 1
+        byte[] bytes = value.getBytes();
+        long result = Ascii.parseLong(bytes, 0, bytes.length);
+        Assert.assertEquals(value, String.valueOf(result));
+    }
+
+
+}

Modified: tomcat/trunk/webapps/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1578812&r1=1578811&r2=1578812&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Tue Mar 18 10:27:31 2014
@@ -165,6 +165,10 @@
         non-blocking IO support that broke handling of requests with an explicit
         content length of zero. (markt/kkolinko)
       </fix>
+      <fix>
+        Fix possible overflow when parsing long values from a byte array.
+        (markt)
+      </fix>
     </changelog>
   </subsection>
   <subsection name="Jasper">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org