You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by se...@apache.org on 2013/12/30 23:55:51 UTC

svn commit: r1554332 - in /commons/proper/net/trunk/src: changes/changes.xml main/java/org/apache/commons/net/util/SubnetUtils.java test/java/org/apache/commons/net/SubnetUtilsTest.java

Author: sebb
Date: Mon Dec 30 22:55:50 2013
New Revision: 1554332

URL: http://svn.apache.org/r1554332
Log:
NET-521 SubnetUtils.SubnetInfo.getAddressCount() can overflow as it returns an int

Modified:
    commons/proper/net/trunk/src/changes/changes.xml
    commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java
    commons/proper/net/trunk/src/test/java/org/apache/commons/net/SubnetUtilsTest.java

Modified: commons/proper/net/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/changes/changes.xml?rev=1554332&r1=1554331&r2=1554332&view=diff
==============================================================================
--- commons/proper/net/trunk/src/changes/changes.xml [utf-8] (original)
+++ commons/proper/net/trunk/src/changes/changes.xml [utf-8] Mon Dec 30 22:55:50 2013
@@ -64,6 +64,9 @@ The <action> type attribute can be add,u
     <body>
         <release version="3.4" date="2013-??-??" description="
         ">
+            <action issue="NET-521" type="fix" dev="sebb">
+            SubnetUtils.SubnetInfo.getAddressCount() can overflow as it returns an int
+            </action>
             <action issue="NET-515" type="fix" due-to="Sebastian Ritter">
             FTPClient sample in class javadoc "bug"
             </action>

Modified: commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java?rev=1554332&r1=1554331&r2=1554332&view=diff
==============================================================================
--- commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java (original)
+++ commons/proper/net/trunk/src/main/java/org/apache/commons/net/util/SubnetUtils.java Mon Dec 30 22:55:50 2013
@@ -90,6 +90,9 @@ public class SubnetUtils {
      *
      */
     public final class SubnetInfo {
+        /* Mask to convert unsigned int to a long (i.e. keep 32 bits) */
+        private static final long UNSIGNED_INT_MASK = 0x0FFFFFFFFL;
+
         private SubnetInfo() {}
 
         private int netmask()       { return netmask; }
@@ -163,9 +166,28 @@ public class SubnetUtils {
          * Get the count of available addresses.
          * Will be zero for CIDR/31 and CIDR/32 if the inclusive flag is false.
          * @return the count of addresses, may be zero.
+         * @throws RuntimeException if the correct count is greater than {@code Integer.MAX_VALUE}
+         * @deprecated use {@link #getAddressCountLong()} instead
+         */
+        @Deprecated
+        public int getAddressCount() {
+            long countLong = getAddressCountLong();
+            if (countLong > Integer.MAX_VALUE) {
+                throw new RuntimeException("Count is larger than an integer: " + countLong);
+            }
+            // N.B. cannot be negative
+            return (int)countLong;
+        }
+
+        /**
+         * Get the count of available addresses.
+         * Will be zero for CIDR/31 and CIDR/32 if the inclusive flag is false.
+         * @return the count of addresses, may be zero.
          */
-        public int getAddressCount()                {
-            int count = broadcast() - network() + (isInclusiveHostCount() ? 1 : -1);
+        public long getAddressCountLong() {
+            long b = broadcast() & UNSIGNED_INT_MASK;
+            long n = network()   & UNSIGNED_INT_MASK;
+            long count = b - n + (isInclusiveHostCount() ? 1 : -1);
             return count < 0 ? 0 : count;
         }
 

Modified: commons/proper/net/trunk/src/test/java/org/apache/commons/net/SubnetUtilsTest.java
URL: http://svn.apache.org/viewvc/commons/proper/net/trunk/src/test/java/org/apache/commons/net/SubnetUtilsTest.java?rev=1554332&r1=1554331&r2=1554332&view=diff
==============================================================================
--- commons/proper/net/trunk/src/test/java/org/apache/commons/net/SubnetUtilsTest.java (original)
+++ commons/proper/net/trunk/src/test/java/org/apache/commons/net/SubnetUtilsTest.java Mon Dec 30 22:55:50 2013
@@ -22,6 +22,7 @@ import org.apache.commons.net.util.Subne
 
 import junit.framework.TestCase;
 
+@SuppressWarnings("deprecation") // deliberate use of deprecated methods
 public class SubnetUtilsTest extends TestCase {
 
     // TODO Lower address test
@@ -311,4 +312,36 @@ public class SubnetUtilsTest extends Tes
         } catch (IllegalArgumentException expected) {
         }
     }
+
+    public void testNET521() {
+        SubnetUtils utils;
+        SubnetInfo info;
+
+        utils = new SubnetUtils("0.0.0.0/0");
+        utils.setInclusiveHostCount(true);
+        info = utils.getInfo();
+        assertEquals("0.0.0.0", info.getNetmask());
+        assertEquals(4294967296L, info.getAddressCountLong());
+        try {
+            info.getAddressCount();
+            fail("Expected RuntimeException");
+        } catch (RuntimeException expected) {
+            // ignored
+        }
+        utils = new SubnetUtils("128.0.0.0/1");
+        utils.setInclusiveHostCount(true);
+        info = utils.getInfo();
+        assertEquals("128.0.0.0", info.getNetmask());
+        assertEquals(2147483648L, info.getAddressCountLong());
+        try {
+            info.getAddressCount();
+            fail("Expected RuntimeException");
+        } catch (RuntimeException expected) {
+            // ignored
+        }
+        // if we exclude the broadcast and network addresses, the count is less than Integer.MAX_VALUE
+        utils.setInclusiveHostCount(false);
+        info = utils.getInfo();
+        assertEquals(2147483646, info.getAddressCount());
+    }
 }