--- a/quid.patch Sun Sep 07 00:38:40 2008 -0700
+++ b/quid.patch Tue Sep 09 12:35:44 2008 -0700
@@ -1,7 +1,7 @@ diff --git a/src/share/classes/com/sun/t
diff --git a/src/share/classes/com/sun/tools/javac/parser/Scanner.java b/src/share/classes/com/sun/tools/javac/parser/Scanner.java
--- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java
+++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java
-@@ -915,6 +915,23 @@
+@@ -915,6 +915,34 @@
lexError(pos, "unclosed.str.lit");
}
return;
@@ -9,14 +9,25 @@ diff --git a/src/share/classes/com/sun/t
+ scanChar();
+ if (ch == '\"') {
+ scanChar();
-+ while (ch != '\"' && ch != CR && ch != LF && bp < buflen)
++ if (ch == '\"')
++ lexError(pos, "empty.bytecode.ident");
++ while (ch != '\"' && ch != CR && ch != LF && bp < buflen) {
++ switch (ch) {
++ // reject any "dangerous" char which is illegal somewhere in the JVM spec
++ // cf. http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm
++ case '/': case '.': case ';': // illegal everywhere
++ case '<': case '>': // illegal in methods, dangerous in classes
++ case '[': // illegal in classes
++ lexError(pos, "illegal.bytecode.ident.char", String.valueOf((int)ch));
++ }
+ scanLitChar();
++ }
+ if (ch == '\"') {
+ name = names.fromChars(sbuf, 0, sp);
+ token = IDENTIFIER; // even if #"int" or #"do"
+ scanChar();
+ } else {
-+ lexError(pos, "unclosed.str.lit");
++ lexError(pos, "unclosed.bytecode.ident");
+ }
+ } else {
+ lexError("illegal.char", String.valueOf((int)'#'));
@@ -25,11 +36,41 @@ diff --git a/src/share/classes/com/sun/t
default:
if (isSpecial(ch)) {
scanOperator();
+diff --git a/src/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties
++++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties
+@@ -144,6 +144,8 @@
+
+ compiler.err.else.without.if=\
+ ''else'' without ''if''
++compiler.err.empty.bytecode.ident=\
++ empty bytecode identifier
+ compiler.err.empty.char.lit=\
+ empty character literal
+ compiler.err.encl.class.required=\
+@@ -186,6 +188,8 @@
+
+ compiler.err.icls.cant.have.static.decl=\
+ inner classes cannot have static declarations
++compiler.err.illegal.bytecode.ident.char=\
++ illegal bytecode identifier character: \\{0}
+ compiler.err.illegal.char=\
+ illegal character: \\{0}
+ compiler.err.illegal.char.for.encoding=\
+@@ -442,6 +446,8 @@
+ compiler.err.types.incompatible.diff.ret=\
+ types {0} and {1} are incompatible; both define {2}, but with unrelated return types
+
++compiler.err.unclosed.bytecode.ident=\
++ unclosed bytecode identifier
+ compiler.err.unclosed.char.lit=\
+ unclosed character literal
+ compiler.err.unclosed.comment=\
diff --git a/test/tools/javac/QuotedIdent.java b/test/tools/javac/QuotedIdent.java
new file mode 100644
--- /dev/null
+++ b/test/tools/javac/QuotedIdent.java
-@@ -0,0 +1,114 @@
+@@ -0,0 +1,121 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -84,6 +125,13 @@ new file mode 100644
+ }
+ }
+
++ /* negative tests, FTR:
++ static class #"" { } // BAD
++ static class #"<foo>" { } // BAD
++ static class #" // BAD
++ " { } // BAD
++ */
++
+ static class #"int" extends Number {
+ final int #"int";
+ #"int"(int #"int") {
@@ -102,7 +150,7 @@ new file mode 100644
+ class #"*86" {
+ String #"555-1212"() { return "[*86.555-1212]"; }
+ }
-+ static #"*86" #"MAKE-*86"() {
++ static#"*86"#"MAKE-*86"() { // note close spacing
+ return new QuotedIdent().new#"*86"();
+ }
+