Bug 559449 - Array index out of bounds in
org.eclipse.jdt.internal.compiler.ClassFile.isLikelyLocalTypeName

Change-Id: I4674c31ba48dfc105be9c2051bc7397bf8817fea
diff --git a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
index 65a5618..376e4b3 100644
--- a/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
+++ b/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/GenericsRegressionTest_1_8.java
@@ -10041,4 +10041,23 @@
 		runner.runConformTest(); // don't use pre-compiled p/X$1.class
 	}
 
+	public void testBug559449() {
+		Runner runner = new Runner();
+		runner.testFiles = new String[] {
+				"p/X.java",
+				"package p;\n" +
+				"public class X {\n" +
+				"	class $$$ {}\n" +
+				"	<S> void m() {\n" +
+				"		Runnable r = () -> {\n" +
+				"			$$$ ddd = new $$$();\n" +
+				"			if (ddd != null)\n" +
+				"				System.out.println(ddd);\n" +
+				"		};\n" +
+				"		r.run();\n" +
+				"	}\n" +
+				"}\n"
+			};
+		runner.runConformTest();
+	}
 }
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
index 7d1ea83..31407fc 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ClassFile.java
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2000, 2019 IBM Corporation and others.
+ * Copyright (c) 2000, 2020 IBM Corporation and others.
  *
  * This program and the accompanying materials
  * are made available under the terms of the Eclipse Public License 2.0
@@ -5980,7 +5980,7 @@
 	
 	private boolean isLikelyLocalTypeName(char[] typeName) {
 		int dollarPos = CharOperation.lastIndexOf('$', typeName);
-		while (dollarPos != -1) {
+		while (dollarPos != -1 && dollarPos+1 < typeName.length) {
 			if (Character.isDigit(typeName[dollarPos+1]))
 				return true; // name segment starts with a digit => likely a local type (but still "$0" etc. could be part of the source name)
 			dollarPos = CharOperation.lastIndexOf('$', typeName, 0, dollarPos-1);