Index: src/java/org/apache/lucene/queryParser/QueryParser.java =================================================================== --- src/java/org/apache/lucene/queryParser/QueryParser.java (revision 468632) +++ src/java/org/apache/lucene/queryParser/QueryParser.java (working copy) @@ -120,7 +120,8 @@ public Query parse(String query) throws ParseException { ReInit(new FastCharStream(new StringReader(query))); try { - return Query(field); + // TopLevelQuery is a Query followed by the end-of-input (EOF) + return TopLevelQuery(field); } catch (ParseException tme) { // rethrow to include the original query: @@ -701,6 +702,15 @@ throw new Error("Missing return statement in function"); } +// This makes sure that there is no garbage after the query string + final public Query TopLevelQuery(String field) throws ParseException { + Query q; + q = Query(field); + jj_consume_token(0); + {if (true) return q;} + throw new Error("Missing return statement in function"); + } + final public Query Query(String field) throws ParseException { Vector clauses = new Vector(); Query q, firstQuery=null; @@ -1260,6 +1270,7 @@ final private void jj_rescan_token() { jj_rescan = true; for (int i = 0; i < 1; i++) { + try { JJCalls p = jj_2_rtns[i]; do { if (p.gen > jj_gen) { @@ -1270,6 +1281,7 @@ } p = p.next; } while (p != null); + } catch(LookaheadSuccess ls) { } } jj_rescan = false; } Index: src/java/org/apache/lucene/queryParser/QueryParser.jj =================================================================== --- src/java/org/apache/lucene/queryParser/QueryParser.jj (revision 468632) +++ src/java/org/apache/lucene/queryParser/QueryParser.jj (working copy) @@ -143,7 +143,8 @@ public Query parse(String query) throws ParseException { ReInit(new FastCharStream(new StringReader(query))); try { - return Query(field); + // TopLevelQuery is a Query followed by the end-of-input (EOF) + return TopLevelQuery(field); } catch (ParseException tme) { // rethrow to include the original query: @@ -747,6 +748,18 @@ { return ret; } } +// This makes sure that there is no garbage after the query string +Query TopLevelQuery(String field) : +{ + Query q; +} +{ + q=Query(field) + { + return q; + } +} + Query Query(String field) : { Vector clauses = new Vector(); Index: src/java/org/apache/lucene/queryParser/QueryParserTokenManager.java =================================================================== --- src/java/org/apache/lucene/queryParser/QueryParserTokenManager.java (revision 468632) +++ src/java/org/apache/lucene/queryParser/QueryParserTokenManager.java (working copy) @@ -945,12 +945,10 @@ private final int[] jjrounds = new int[35]; private final int[] jjstateSet = new int[70]; protected char curChar; -public QueryParserTokenManager(CharStream stream) -{ +public QueryParserTokenManager(CharStream stream){ input_stream = stream; } -public QueryParserTokenManager(CharStream stream, int lexState) -{ +public QueryParserTokenManager(CharStream stream, int lexState){ this(stream); SwitchTo(lexState); } Index: src/test/org/apache/lucene/queryParser/TestMultiFieldQueryParser.java =================================================================== --- src/test/org/apache/lucene/queryParser/TestMultiFieldQueryParser.java (revision 468632) +++ src/test/org/apache/lucene/queryParser/TestMultiFieldQueryParser.java (working copy) @@ -54,7 +54,7 @@ q = mfqp.parse("+one +two"); assertEquals("+(b:one t:one) +(b:two t:two)", q.toString()); - q = mfqp.parse("+one -two -three)"); + q = mfqp.parse("+one -two -three"); assertEquals("+(b:one t:one) -(b:two t:two) -(b:three t:three)", q.toString()); q = mfqp.parse("one^2 two"); Index: src/test/org/apache/lucene/queryParser/TestQueryParser.java =================================================================== --- src/test/org/apache/lucene/queryParser/TestQueryParser.java (revision 468632) +++ src/test/org/apache/lucene/queryParser/TestQueryParser.java (working copy) @@ -573,14 +573,24 @@ assertEquals(1.0f, q.getBoost(), 0.01f); } - public void testException() throws Exception { + public void assertParseException(String queryString) throws Exception { try { - assertQueryEquals("\"some phrase", null, "abc"); - fail("ParseException expected, not thrown"); + Query q = getQuery(queryString, null); } catch (ParseException expected) { + return; } + fail("ParseException expected, not thrown"); } + public void testException() throws Exception { + assertParseException("\"some phrase"); + assertParseException("(foo bar"); + assertParseException("foo bar))"); + assertParseException("field:term:with:colon some more terms"); + assertParseException("(sub query)^5.0^2.0 plus more"); + assertParseException("secret AND illegal) AND access:confidential"); + } + public void testCustomQueryParserWildcard() { try { new QPTestParser("contents", new WhitespaceAnalyzer()).parse("a?t");