### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java,v retrieving revision 1.198 diff -u -r1.198 Scanner.java --- compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java 21 Oct 2009 16:19:38 -0000 1.198 +++ compiler/org/eclipse/jdt/internal/compiler/parser/Scanner.java 12 Nov 2009 19:54:30 -0000 @@ -1379,6 +1379,9 @@ } while (this.currentCharacter != '"') { + if (this.currentPosition >= this.eofPosition) { + throw new InvalidInputException(UNTERMINATED_STRING); + } /**** \r and \n are not valid in string literals ****/ if ((this.currentCharacter == '\n') || (this.currentCharacter == '\r')) { // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed @@ -1486,6 +1489,12 @@ } //jump over the \\ boolean isUnicode = false; while (this.currentCharacter != '\r' && this.currentCharacter != '\n') { + if (this.currentPosition >= this.eofPosition) { + this.lastCommentLinePosition = this.currentPosition; + this.currentPosition ++; + // this avoids duplicating the code in the catch(IndexOutOfBoundsException e) + throw new IndexOutOfBoundsException(); + } this.lastCommentLinePosition = this.currentPosition; //get the next char isUnicode = false; @@ -1504,16 +1513,16 @@ * We need to completely consume the line break */ if (this.currentCharacter == '\r' - && this.eofPosition > this.currentPosition) { - if (this.source[this.currentPosition] == '\n') { + && this.eofPosition > this.currentPosition) { + if (this.source[this.currentPosition] == '\n') { this.currentPosition++; this.currentCharacter = '\n'; - } else if ((this.source[this.currentPosition] == '\\') + } else if ((this.source[this.currentPosition] == '\\') && (this.source[this.currentPosition + 1] == 'u')) { getNextUnicodeChar(); isUnicode = true; } - } + } recordComment(TokenNameCOMMENT_LINE); if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition); if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) { @@ -1601,6 +1610,9 @@ //loop until end of comment */ int firstTag = 0; while ((this.currentCharacter != '/') || (!star)) { + if (this.currentPosition >= this.eofPosition) { + throw new InvalidInputException(UNTERMINATED_COMMENT); + } if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) { if (this.recordLineSeparator) { if (isUnicode) { @@ -1865,13 +1877,16 @@ getNextUnicodeChar(); } else { if (this.withoutUnicodePtr != 0) { - unicodeStore(); + unicodeStore(); } } } catch (InvalidInputException ex) { // ignore } while (this.currentCharacter != '"') { + if (this.currentPosition >= this.eofPosition) { + return; + } if (this.currentCharacter == '\r'){ if (this.source[this.currentPosition] == '\n') this.currentPosition++; break NextToken; // the string cannot go further that the line @@ -1935,6 +1950,12 @@ } //jump over the \\ boolean isUnicode = false; while (this.currentCharacter != '\r' && this.currentCharacter != '\n') { + if (this.currentPosition >= this.eofPosition) { + this.lastCommentLinePosition = this.currentPosition; + this.currentPosition ++; + // this avoids duplicating the code inside the catch(IndexOutOfBoundsException e) below + throw new IndexOutOfBoundsException(); + } this.lastCommentLinePosition = this.currentPosition; //get the next char isUnicode = false; @@ -1953,16 +1974,16 @@ * We need to completely consume the line break */ if (this.currentCharacter == '\r' - && this.eofPosition > this.currentPosition) { - if (this.source[this.currentPosition] == '\n') { + && this.eofPosition > this.currentPosition) { + if (this.source[this.currentPosition] == '\n') { this.currentPosition++; this.currentCharacter = '\n'; - } else if ((this.source[this.currentPosition] == '\\') + } else if ((this.source[this.currentPosition] == '\\') && (this.source[this.currentPosition + 1] == 'u')) { isUnicode = true; getNextUnicodeChar(); } - } + } recordComment(TokenNameCOMMENT_LINE); if (this.recordLineSeparator && ((this.currentCharacter == '\r') || (this.currentCharacter == '\n'))) { @@ -2007,7 +2028,7 @@ } else { isUnicode = false; if (this.withoutUnicodePtr != 0) { - unicodeStore(); + unicodeStore(); } } @@ -2045,6 +2066,9 @@ //loop until end of comment */ int firstTag = 0; while ((this.currentCharacter != '/') || (!star)) { + if (this.currentPosition >= this.eofPosition) { + return; + } if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) { if (this.recordLineSeparator) { if (isUnicode) { Index: model/org/eclipse/jdt/internal/core/util/PublicScanner.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/PublicScanner.java,v retrieving revision 1.111 diff -u -r1.111 PublicScanner.java --- model/org/eclipse/jdt/internal/core/util/PublicScanner.java 21 Oct 2009 16:19:39 -0000 1.111 +++ model/org/eclipse/jdt/internal/core/util/PublicScanner.java 12 Nov 2009 19:54:31 -0000 @@ -1376,6 +1376,9 @@ } while (this.currentCharacter != '"') { + if (this.currentPosition >= this.eofPosition) { + throw new InvalidInputException(UNTERMINATED_STRING); + } /**** \r and \n are not valid in string literals ****/ if ((this.currentCharacter == '\n') || (this.currentCharacter == '\r')) { // relocate if finding another quote fairly close: thus unicode '/u000D' will be fully consumed @@ -1483,6 +1486,11 @@ } //jump over the \\ boolean isUnicode = false; while (this.currentCharacter != '\r' && this.currentCharacter != '\n') { + if (this.currentPosition >= this.eofPosition) { + this.currentPosition++; + // this avoids duplicating the code in the catch(IndexOutOfBoundsException e) + throw new IndexOutOfBoundsException(); + } this.lastCommentLinePosition = this.currentPosition; //get the next char isUnicode = false; @@ -1501,16 +1509,16 @@ * We need to completely consume the line break */ if (this.currentCharacter == '\r' - && this.eofPosition > this.currentPosition) { - if (this.source[this.currentPosition] == '\n') { + && this.eofPosition > this.currentPosition) { + if (this.source[this.currentPosition] == '\n') { this.currentPosition++; this.currentCharacter = '\n'; - } else if ((this.source[this.currentPosition] == '\\') + } else if ((this.source[this.currentPosition] == '\\') && (this.source[this.currentPosition + 1] == 'u')) { getNextUnicodeChar(); isUnicode = true; } - } + } recordComment(TokenNameCOMMENT_LINE); if (this.taskTags != null) checkTaskTag(this.startPosition, this.currentPosition); if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) { @@ -1598,6 +1606,9 @@ //loop until end of comment */ int firstTag = 0; while ((this.currentCharacter != '/') || (!star)) { + if (this.currentPosition >= this.eofPosition) { + throw new InvalidInputException(UNTERMINATED_COMMENT); + } if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) { if (this.recordLineSeparator) { if (isUnicode) { @@ -1862,13 +1873,16 @@ getNextUnicodeChar(); } else { if (this.withoutUnicodePtr != 0) { - unicodeStore(); + unicodeStore(); } } } catch (InvalidInputException ex) { // ignore } while (this.currentCharacter != '"') { + if (this.currentPosition >= this.eofPosition) { + return; + } if (this.currentCharacter == '\r'){ if (this.source[this.currentPosition] == '\n') this.currentPosition++; break NextToken; // the string cannot go further that the line @@ -1932,6 +1946,11 @@ } //jump over the \\ boolean isUnicode = false; while (this.currentCharacter != '\r' && this.currentCharacter != '\n') { + if (this.currentPosition >= this.eofPosition) { + this.currentPosition++; + // this avoids duplicating the code inside the catch(IndexOutOfBoundsException e) below + throw new IndexOutOfBoundsException(); + } this.lastCommentLinePosition = this.currentPosition; //get the next char isUnicode = false; @@ -1950,16 +1969,16 @@ * We need to completely consume the line break */ if (this.currentCharacter == '\r' - && this.eofPosition > this.currentPosition) { - if (this.source[this.currentPosition] == '\n') { + && this.eofPosition > this.currentPosition) { + if (this.source[this.currentPosition] == '\n') { this.currentPosition++; this.currentCharacter = '\n'; - } else if ((this.source[this.currentPosition] == '\\') + } else if ((this.source[this.currentPosition] == '\\') && (this.source[this.currentPosition + 1] == 'u')) { isUnicode = true; getNextUnicodeChar(); } - } + } recordComment(TokenNameCOMMENT_LINE); if (this.recordLineSeparator && ((this.currentCharacter == '\r') || (this.currentCharacter == '\n'))) { @@ -2004,7 +2023,7 @@ } else { isUnicode = false; if (this.withoutUnicodePtr != 0) { - unicodeStore(); + unicodeStore(); } } @@ -2042,6 +2061,9 @@ //loop until end of comment */ int firstTag = 0; while ((this.currentCharacter != '/') || (!star)) { + if (this.currentPosition >= this.eofPosition) { + return; + } if ((this.currentCharacter == '\r') || (this.currentCharacter == '\n')) { if (this.recordLineSeparator) { if (isUnicode) { #P org.eclipse.jdt.core.tests.compiler Index: src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java,v retrieving revision 1.32 diff -u -r1.32 ScannerTest.java --- src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java 21 Oct 2009 16:19:40 -0000 1.32 +++ src/org/eclipse/jdt/core/tests/compiler/regression/ScannerTest.java 12 Nov 2009 19:54:31 -0000 @@ -31,7 +31,7 @@ // All specified tests which does not belong to the class are skipped... static { // TESTS_NAMES = new String[] { "test000" }; -// TESTS_NUMBERS = new int[] { 46 }; +// TESTS_NUMBERS = new int[] { 52 }; // TESTS_RANGE = new int[] { 11, -1 }; } @@ -1017,4 +1017,114 @@ assertTrue("Wrong exception", false); } } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=294529 + public void test047() { + IScanner scanner = ToolFactory.createScanner( + true, + true, + true, + JavaCore.getOption(JavaCore.COMPILER_SOURCE), + JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE)); + final char[] source = "// a comment, longer than the offset".toCharArray(); + scanner.setSource(source); + scanner.resetTo(0, 5); + try { + assertEquals("Wrong token", ITerminalSymbols.TokenNameCOMMENT_LINE, scanner.getNextToken()); + assertEquals("Wrong source", "// a c", new String(scanner.getCurrentTokenSource())); + assertEquals("Wrong token", ITerminalSymbols.TokenNameEOF, scanner.getNextToken()); + } catch (InvalidInputException e) { + assertTrue("Wrong exception", false); + } + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=294529 + public void test048() { + IScanner scanner = ToolFactory.createScanner( + true, + true, + true, + JavaCore.getOption(JavaCore.COMPILER_SOURCE), + JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE)); + final char[] source = "/*a comment, longer\n than the\noffset*/".toCharArray(); + scanner.setSource(source); + scanner.resetTo(0, 5); + try { + assertEquals("Wrong token", ITerminalSymbols.TokenNameCOMMENT_BLOCK, scanner.getNextToken()); + assertTrue("Should fail with InvalidInputException", false); + } catch (InvalidInputException e) { + assertEquals("Wrong source", "/*a co", new String(scanner.getCurrentTokenSource())); + } + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=294529 + public void test049() { + IScanner scanner = ToolFactory.createScanner( + true, + true, + true, + JavaCore.getOption(JavaCore.COMPILER_SOURCE), + JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE)); + final char[] source = "/*a coabstract, longer\n than the\noffset*/".toCharArray(); + scanner.setSource(source); + scanner.resetTo(6, 13); + try { + assertEquals("Wrong token", ITerminalSymbols.TokenNameabstract, scanner.getNextToken()); + assertEquals("Wrong source", "abstract", new String(scanner.getCurrentTokenSource())); + assertEquals("Wrong token", ITerminalSymbols.TokenNameEOF, scanner.getNextToken()); + } catch (InvalidInputException e) { + assertTrue("Wrong exception", false); + } + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=294529 + public void test050() { + IScanner scanner = ToolFactory.createScanner( + true, + true, + true, + JavaCore.getOption(JavaCore.COMPILER_SOURCE), + JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE)); + final char[] source = "\"a comment, longer\\n than the\\noffset \"".toCharArray(); + scanner.setSource(source); + scanner.resetTo(0, 5); + try { + assertEquals("Wrong token", ITerminalSymbols.TokenNameStringLiteral, scanner.getNextToken()); + assertTrue("Should fail with InvalidInputException", false); + } catch (InvalidInputException e) { + assertEquals("Wrong source", "\"a com", new String(scanner.getCurrentTokenSource())); + } + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=294529 + public void test051() { + IScanner scanner = ToolFactory.createScanner( + true, + true, + true, + JavaCore.getOption(JavaCore.COMPILER_SOURCE), + JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE)); + final char[] source = "\"a co\\u00E9mment, longer\\n than the\\noffset \"".toCharArray(); + scanner.setSource(source); + scanner.resetTo(0, 5); + try { + assertEquals("Wrong token", ITerminalSymbols.TokenNameStringLiteral, scanner.getNextToken()); + assertTrue("Should fail with InvalidInputException", false); + } catch (InvalidInputException e) { + assertEquals("Wrong source", "\"a co\\", new String(scanner.getCurrentTokenSource())); + } + } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=294529 + public void test052() { + IScanner scanner = ToolFactory.createScanner( + true, + true, + true, + JavaCore.getOption(JavaCore.COMPILER_SOURCE), + JavaCore.getOption(JavaCore.COMPILER_COMPLIANCE)); + final char[] source = "\"\\u00E9mment, longer\\n than the\\noffset \"".toCharArray(); + scanner.setSource(source); + scanner.resetTo(0, 5); + try { + assertEquals("Wrong token", ITerminalSymbols.TokenNameStringLiteral, scanner.getNextToken()); + assertTrue("Should fail with InvalidInputException", false); + } catch (InvalidInputException e) { + assertEquals("Wrong source", "\"\\u00E", new String(scanner.getCurrentTokenSource())); + } + } }