changeset 24165:fbcbf83757cb

bad signatures should be detected by MetaAccessProvider.parseMethodDescriptor (JDK-8186163)
author Doug Simon <doug.simon@oracle.com>
date Sat, 12 Aug 2017 12:40:51 +0200
parents f98ea2d742a2
children dad95e57f1de
files jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java
diffstat 3 files changed, 54 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java	Tue Aug 08 10:06:50 2017 +0200
+++ b/jvmci/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotSignature.java	Sat Aug 12 12:40:51 2017 +0200
@@ -25,7 +25,6 @@
 import java.util.ArrayList;
 import java.util.List;
 
-import jdk.vm.ci.common.JVMCIError;
 import jdk.vm.ci.meta.JavaKind;
 import jdk.vm.ci.meta.JavaType;
 import jdk.vm.ci.meta.ResolvedJavaType;
@@ -45,7 +44,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 +60,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 +84,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/jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java	Tue Aug 08 10:06:50 2017 +0200
+++ b/jvmci/jdk.vm.ci.meta/src/jdk/vm/ci/meta/MetaAccessProvider.java	Sat Aug 12 12:40:51 2017 +0200
@@ -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/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java	Tue Aug 08 10:06:50 2017 +0200
+++ b/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestMetaAccessProvider.java	Sat Aug 12 12:40:51 2017 +0200
@@ -101,4 +101,15 @@
             }
         }
     }
+
+    @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) {
+            }
+        }
+    }
 }