You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by lv...@apache.org on 2009/01/07 09:35:52 UTC

svn commit: r732272 - in /harmony/enhanced/classlib/trunk/modules/luni/src: main/java/java/net/SocketPermission.java main/java/org/apache/harmony/luni/util/Inet6Util.java test/api/common/org/apache/harmony/luni/tests/java/net/SocketPermissionTest.java

Author: lvjing
Date: Wed Jan  7 00:35:52 2009
New Revision: 732272

URL: http://svn.apache.org/viewvc?rev=732272&view=rev
Log:
Apply patch for HARMONY-6028 [classlib][luni] Unvalid IPv6 address is allowed in the SocketPermission

Modified:
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/SocketPermission.java
    harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java
    harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/net/SocketPermissionTest.java

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/SocketPermission.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/SocketPermission.java?rev=732272&r1=732271&r2=732272&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/SocketPermission.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/SocketPermission.java Wed Jan  7 00:35:52 2009
@@ -131,7 +131,7 @@
         setActions(action);
         actions = toCanonicalActionString(action);
         // Use host since we are only checking for port presence
-        parsePort(host);
+        parsePort(host, hostName);
     }
 
     /**
@@ -226,6 +226,7 @@
             } else if (action.equals(actionNames[SP_ACCEPT])) {
                 actionsMask |= SP_ACCEPT;
             } else if (action.equals(actionNames[SP_RESOLVE])) {
+                // do nothing
             } else {
                 throw new IllegalArgumentException(Msg.getString("K0048", //$NON-NLS-1$
                         action));
@@ -281,70 +282,61 @@
     public PermissionCollection newPermissionCollection() {
         return new SocketPermissionCollection();
     }
-
+    
     /**
-     * Parses the port string into the lower and higher bound of the port range.
-     * 
+     * Parse the port, including the minPort, maxPort
+     * @param hostPort the host[:port] one
+     * @param host the host name we just get
+     * @throws IllegalArgumentException If the port is not a positive number or minPort
+     *                                  is not less than or equal maxPort
      */
-    private void parsePort(String hostString) throws IllegalArgumentException {
-        int negidx = -1;
-        int len = -1;
-        int lastIdx = hostString.lastIndexOf(':');
-        int idx = hostString.indexOf(':');
-        int endOfIPv6Addr = hostString.lastIndexOf(']');
-        if ((endOfIPv6Addr == -1) && (idx != lastIdx)) {
-            // there are no square braces, but there are more than one ':' which
-            // implies an IPv6 address with no port, or an illegal argument
-            // check for valid IPv6 address
-            if (Inet6Util.isValidIP6Address(hostString)) {
-                return;
-            }
-            // throw an invalid argument exception
-            throw new IllegalArgumentException(Msg.getString("K004a")); //$NON-NLS-1$
-        }
-        // if there is a colon and it occurs after the ']' then there is a port
-        // to be parsed
-        if ((lastIdx > -1) && (lastIdx > endOfIPv6Addr)) {
-            try {
-                len = hostString.length();
-                // if hostString ends with ":*", such as "localhost:*"
-                // the port range should be 0-65535
-                if (hostString.endsWith(":*")) { //$NON-NLS-1$
-                    portMin = 0;
-                    portMax = 65535;
-                    return;
-                }
-                // look for a '-' after the colon
-                negidx = hostString.indexOf('-', lastIdx);
-                if (negidx == lastIdx + 1) {
-                    portMax = Integer.parseInt(hostString.substring(
-                            lastIdx + 2, len));
-                } else {
-                    // A port range was provided
-                    if (negidx != -1 && (negidx != len - 1)) {
-                        portMin = Integer.parseInt(hostString.substring(
-                                lastIdx + 1, negidx));
-                        portMax = Integer.parseInt(hostString.substring(
-                                negidx + 1, len));
-                    } else {
-                        if (negidx == -1) {
-                            portMin = Integer.parseInt(hostString.substring(
-                                    lastIdx + 1, len));
-                            portMax = portMin;
-                        } else {
-                            portMin = Integer.parseInt(hostString.substring(
-                                    lastIdx + 1, negidx));
-                        }
-                    }
-                }
-                if (portMax < portMin) {
-                    throw new IllegalArgumentException(Msg.getString("K0049")); //$NON-NLS-1$
-                }
-
-            } catch (NumberFormatException e) {
-                throw new IllegalArgumentException(Msg.getString("K004a")); //$NON-NLS-1$
-            }
-        }
+    private void parsePort(String hostPort, String host) throws IllegalArgumentException {
+       String port = hostPort.substring(host.length());
+       String emptyString = ""; //$NON-NLS-1$
+
+       if (emptyString.equals(port)) {
+           // Not specified
+           portMin = 80;
+           portMax = 80;
+           return;
+       }
+       
+       if (":*".equals(port)) {
+           // The port range should be 0-65535
+           portMin = 0;
+           portMax = 65535;
+           return;
+       }
+       
+       // Omit ':'
+       port = port.substring(1);
+       int negIdx = port.indexOf('-');
+       String strPortMin = emptyString;
+       String strPortMax = emptyString;
+       if (-1 == negIdx) {
+           // No neg mark, only one number
+           strPortMin = port;
+           strPortMax = port;
+       } else {
+           strPortMin = port.substring(0, negIdx);
+           strPortMax = port.substring(negIdx + 1);
+           if (emptyString.equals(strPortMin)) {
+               strPortMin = "0";
+           }
+           if (emptyString.equals(strPortMax)) {
+               strPortMax = "65535";
+           }
+       }
+       try {
+           portMin = Integer.valueOf(strPortMin).intValue();
+           portMax = Integer.valueOf(strPortMax).intValue();
+           
+           if (portMin > portMax) {
+               throw new IllegalArgumentException(Msg.getString("K0049") + " " + port); //$NON-NLS-1$
+           }
+       } catch (NumberFormatException e) {
+           throw new IllegalArgumentException(Msg.getString("K004a") + " " + port); //$NON-NLS-1$
+       }
     }
 
     /**
@@ -384,13 +376,26 @@
             try {
                 ipString = InetAddress.getHostNameInternal(hostName);
             } catch (UnknownHostException e) {
+                // ignore
             }
             resolved = true;
         }
         return ipString;
     }
 
+    /**
+     * Get the host part from the host[:port] one.
+     * The host should be
+     *      host = (hostname | IPv4address | IPv6reference | IPv6 in full uncompressed form)
+     * The wildcard "*" may be included once in a DNS name host specification. If it is included, 
+     * it must be in the leftmost position
+     * 
+     * @param host
+     * @return
+     * @throws IllegalArgumentException   if the host is invalid.
+     */
     private String getHostString(String host) throws IllegalArgumentException {
+        host = host.trim();
         int idx = -1;
         idx = host.indexOf(':');
         isPartialWild = (host.length() > 0 && host.charAt(0) == '*');
@@ -407,22 +412,46 @@
         }
 
         int lastIdx = host.lastIndexOf(':');
-        if ((idx > -1) && (idx == lastIdx)) {
-            host = host.substring(0, idx);
-        } else {
-            // likely host is or contains an IPv6 address
-            if (lastIdx != -1) {
-                if (Inet6Util.isValidIP6Address(host)) {
-                    return host.toLowerCase();
-                } else if (Inet6Util.isValidIP6Address(host.substring(0,
-                        lastIdx))) {
-                    host = host.substring(0, lastIdx);
-                } else {
-                    throw new IllegalArgumentException(Msg.getString("K004a")); //$NON-NLS-1$
+        
+        if (idx == lastIdx) {
+            if (-1 != idx) {
+                // only one colon, should be port
+                host = host.substring(0, idx);
+            }
+            return host.toLowerCase();
+        }
+            // maybe ipv6
+        boolean isFirstBracket = (host.charAt(0) == '[');
+        if (!isFirstBracket) {
+            // No bracket, should be in full form
+            int colonNum = 0;
+            for (int i = 0; i < host.length(); ++i) {
+                if (host.charAt(i) == ':') {
+                    colonNum++;
                 }
             }
+            // Get rid of the colon before port
+            if (8 == colonNum) {
+                host = host.substring(0, lastIdx);
+            }
+            if (Inet6Util.isIP6AddressInFullForm(host)) {
+                return host.toLowerCase();
+            }
+            throw new IllegalArgumentException(Msg.getString("K004a") + " "
+                    + host);
+        }
+        // forward bracket found
+        int bbracketIdx = host.indexOf(']');
+        if (-1 == bbracketIdx) {
+            // no back bracket found, wrong
+            throw new IllegalArgumentException(Msg.getString("K004a") + " "
+                    + host);
+        }
+        host = host.substring(0, bbracketIdx + 1);
+        if (Inet6Util.isValidIP6Address(host)) {
+            return host.toLowerCase();
         }
-        return host.toLowerCase();
+        throw new IllegalArgumentException(Msg.getString("K004a") + " " + host);
     }
 
     /*
@@ -458,7 +487,7 @@
         portMax = HIGHEST_PORT;
         actionsMask = SP_RESOLVE;
         hostName = getHostString(getName());
-        parsePort(getName());
+        parsePort(getName(), hostName);
         setActions(actions);
     }
 }

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java?rev=732272&r1=732271&r2=732272&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/util/Inet6Util.java Wed Jan  7 00:35:52 2009
@@ -293,6 +293,18 @@
 				+ ((value >> 8) & 0xff) + "." + (value & 0xff);
 	}
 
+    public static boolean isIP6AddressInFullForm(String ipAddress) {
+        if (isValidIP6Address(ipAddress)) {
+            int doubleColonIndex = ipAddress.indexOf("::");
+            if (doubleColonIndex >= 0) {
+                // Simplified form which contains ::
+                return false;
+            }
+            return true;
+        }
+        return false;
+    }
+    
 	public static boolean isValidIP6Address(String ipAddress) {
 		int length = ipAddress.length();
 		boolean doubleColon = false;

Modified: harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/net/SocketPermissionTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/net/SocketPermissionTest.java?rev=732272&r1=732271&r2=732272&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/net/SocketPermissionTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/luni/src/test/api/common/org/apache/harmony/luni/tests/java/net/SocketPermissionTest.java Wed Jan  7 00:35:52 2009
@@ -204,4 +204,33 @@
 
         SerializationTest.verifySelf(permission);
     }
+    
+    public void test_ConstructorLjava_lang_StringLjava_lang_String_subtestIPv6() {
+        String[] goodTestStrings = { 
+                "12334.0.0.01", "[fe80::1]",
+                "[FE80:0000:0000:0000:0000:0000:0000:0001]:80",
+                "[::ffff]:80-82", "[ffff::]:80-82", "[fe80::1]:80",
+                "FE80:0000:0000:0000:0000:0000:0000:0001",
+                "FE80:0000:0000:0000:0000:0000:0000:0001:80"
+        };
+        String[] badTestStrings = {"someName:withColonInit:80", "fg80::1", "[ffff:::80-82]",
+                ":[:fff]:80", "FE80:0000:0000:0000:0000:0000:0000:0001:80:82", "FE80::1"
+        };
+        
+        for (int i=0; i < goodTestStrings.length; i++) {
+            try {
+                SocketPermission sp = new SocketPermission(goodTestStrings[i], "connect");
+            } catch (IllegalArgumentException e) {
+                e.printStackTrace();
+                fail("SocketPermission named: " + goodTestStrings[i] + " failed construction: " + e.getMessage());
+            }
+        }
+        
+        for (int i=0; i < badTestStrings.length; i++) {
+            try {
+                SocketPermission sp = new SocketPermission(badTestStrings[i], "connect");
+                fail("SocketPermission named: " + badTestStrings[i] + " should have thrown an IllegalArgumentException on construction");
+            } catch (IllegalArgumentException e) {}
+        }
+    }
 }