8186163: [JVMCI] bad signatures should be detected by MetaAccessProvider.parseMethodDescriptor
Reviewed-by: kvn, iveresov
--- 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) {
+ }
+ }
+ }
}