8186163: [JVMCI] bad signatures should be detected by MetaAccessProvider.parseMethodDescriptor
authordnsimon
Mon, 14 Aug 2017 14:15:56 -0700
changeset 46970 449f80716e59
parent 46964 7bdccf51db41
child 46971 8d189e2ebebd
8186163: [JVMCI] bad signatures should be detected by MetaAccessProvider.parseMethodDescriptor Reviewed-by: kvn, iveresov
hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java
hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java
hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java
--- a/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java	Wed Aug 23 18:28:45 2017 +0000
+++ b/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java	Mon Aug 14 14:15:56 2017 -0700
@@ -45,7 +45,9 @@
 
     public HotSpotSignature(HotSpotJVMCIRuntimeProvider runtime, String signature) {
         this.runtime = runtime;
-        assert signature.length() > 0;
+        if (signature.length() == 0) {
+            throw new IllegalArgumentException("Signature cannot be empty");
+        }
         this.originalString = signature;
 
         if (signature.charAt(0) == '(') {
@@ -59,9 +61,11 @@
             cur++;
             int nextCur = parseSignature(signature, cur);
             returnType = signature.substring(cur, nextCur);
-            assert nextCur == signature.length();
+            if (nextCur != signature.length()) {
+                throw new IllegalArgumentException("Extra characters at end of signature: " + signature);
+            }
         } else {
-            returnType = null;
+            throw new IllegalArgumentException("Signature must start with a '(': " + signature);
         }
     }
 
@@ -81,33 +85,41 @@
     }
 
     private static int parseSignature(String signature, int start) {
-        int cur = start;
-        char first;
-        do {
-            first = signature.charAt(cur++);
-        } while (first == '[');
-
-        switch (first) {
-            case 'L':
-                while (signature.charAt(cur) != ';') {
-                    cur++;
-                }
+        try {
+            int cur = start;
+            char first;
+            do {
+                first = signature.charAt(cur);
                 cur++;
-                break;
-            case 'V':
-            case 'I':
-            case 'B':
-            case 'C':
-            case 'D':
-            case 'F':
-            case 'J':
-            case 'S':
-            case 'Z':
-                break;
-            default:
-                throw new JVMCIError("Invalid character at index %d in signature: %s", cur, signature);
+            } while (first == '[');
+
+            switch (first) {
+                case 'L':
+                    while (signature.charAt(cur) != ';') {
+                        if (signature.charAt(cur) == '.') {
+                            throw new IllegalArgumentException("Class name in signature contains '.' at index " + cur + ": " + signature);
+                        }
+                        cur++;
+                    }
+                    cur++;
+                    break;
+                case 'V':
+                case 'I':
+                case 'B':
+                case 'C':
+                case 'D':
+                case 'F':
+                case 'J':
+                case 'S':
+                case 'Z':
+                    break;
+                default:
+                    throw new IllegalArgumentException("Invalid character '" + signature.charAt(cur - 1) + "' at index " + (cur - 1) + " in signature: " + signature);
+            }
+            return cur;
+        } catch (StringIndexOutOfBoundsException e) {
+            throw new IllegalArgumentException("Truncated signature: " + signature);
         }
-        return cur;
     }
 
     @Override
--- a/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java	Wed Aug 23 18:28:45 2017 +0000
+++ b/hotspot/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java	Mon Aug 14 14:15:56 2017 -0700
@@ -83,8 +83,9 @@
     /**
      * Parses a
      * <a href="http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.3.3">method
-     * descriptor</a> into a {@link Signature}. The behavior of this method is undefined if the
-     * method descriptor is not well formed.
+     * descriptor</a> into a {@link Signature}.
+     *
+     * @throws IllegalArgumentException if the method descriptor is not well formed
      */
     Signature parseMethodDescriptor(String methodDescriptor);
 
--- a/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java	Wed Aug 23 18:28:45 2017 +0000
+++ b/hotspot/test/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java	Mon Aug 14 14:15:56 2017 -0700
@@ -257,4 +257,15 @@
             assertEquals("Unexpected debugId", metaAccess.decodeDebugId(value), DEBUG_IDS[i]);
         }
     }
+
+    @Test
+    public void parseSignatureTest() {
+        for (String badSig : new String[]{"", "()", "(", "()Vextra", "()E", "(E)", "(Ljava.lang.Object;)V"}) {
+            try {
+                metaAccess.parseMethodDescriptor(badSig);
+                throw new AssertionError("Expected signature to be invalid: " + badSig);
+            } catch (IllegalArgumentException e) {
+            }
+        }
+    }
 }