From 077fbb67ae1499b0843456b47f121370f616af22 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Mon, 12 Jun 2006 01:08:32 +0000 Subject: [PATCH] Fix for bug 126136 - Out of memory error on recursive macro --- .../parser/tests/scanner2/Scanner2Test.java | 16 ++++++-- .../core/parser/scanner2/BaseScanner.java | 41 +++++++++++++++++-- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/Scanner2Test.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/Scanner2Test.java index 9f5525dea6e..a63af7a449a 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/Scanner2Test.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner2/Scanner2Test.java @@ -355,7 +355,7 @@ public class Scanner2Test extends BaseScanner2Test "#else\n" + //$NON-NLS-1$ "bar\n" + //$NON-NLS-1$ "#endif\n" //$NON-NLS-1$ - ); //$NON-NLS-1$ + ); validateIdentifier("foo"); //$NON-NLS-1$ validateEOF(); initializeScanner( @@ -364,7 +364,7 @@ public class Scanner2Test extends BaseScanner2Test "#else\n" + //$NON-NLS-1$ "bar\n" + //$NON-NLS-1$ "#endif\n" //$NON-NLS-1$ - ); //$NON-NLS-1$ + ); validateIdentifier("foo"); //$NON-NLS-1$ validateEOF(); } @@ -2380,7 +2380,7 @@ public class Scanner2Test extends BaseScanner2Test validateToken( IToken.tRPAREN ); validateToken( IToken.tLBRACE ); validateToken( IToken.t_return ); - validateInteger( "0" ); + validateInteger( "0" ); //$NON-NLS-1$ validateToken( IToken.tSEMI ); validateToken( IToken.tRBRACE ); validateEOF(); @@ -2400,10 +2400,18 @@ public class Scanner2Test extends BaseScanner2Test validateToken( IToken.tRPAREN ); validateToken( IToken.tLBRACE ); validateToken( IToken.t_return ); - validateInteger( "0" ); + validateInteger( "0" ); //$NON-NLS-1$ validateToken( IToken.tSEMI ); validateToken( IToken.tRBRACE ); validateEOF(); } + public void testBug126136() throws Exception { + StringBuffer buffer = new StringBuffer("#define C C\n"); //$NON-NLS-1$ + buffer.append("#if !C\n"); //$NON-NLS-1$ + buffer.append("true\n"); //$NON-NLS-1$ + buffer.append("#endif\n"); //$NON-NLS-1$ + initializeScanner(buffer.toString(), ParserLanguage.CPP); + fullyTokenize(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java index 307b451d910..c935a58bfae 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner2/BaseScanner.java @@ -660,8 +660,24 @@ abstract class BaseScanner implements IScanner { } else if (expObject instanceof ObjectStyleMacro) { ObjectStyleMacro expMacro = (ObjectStyleMacro) expObject; char[] expText = expMacro.getExpansion(); - if (expText.length > 0) - pushContext(expText, expMacro); + if (expText.length > 0 ) + { + if (shouldExpandMacro(expMacro, bufferStackPos, bufferData, -1, bufferPos, bufferStack )) + pushContext(expText, new MacroData(start, start + len, expMacro)); + else + { + if (len == 1) { // is a character + tokenType = tCHAR; + return; + } + // undefined macro, assume 0 + tokenValue = 0; + tokenType = tNUMBER; + return; + + } + + } } else if (expObject instanceof char[]) { char[] expText = (char[]) expObject; if (expText.length > 0) @@ -2135,9 +2151,14 @@ abstract class BaseScanner implements IScanner { * @return */ protected boolean shouldExpandMacro(IMacro macro) { + return shouldExpandMacro(macro, bufferStackPos, bufferData, offsetBoundary, bufferPos, bufferStack); + } + + protected static boolean shouldExpandMacro(IMacro macro, int bufferStackPos, Object [] bufferData, int offsetBoundary, int [] bufferPos, char [][]bufferStack ) + { // but not if it has been expanded on the stack already // i.e. recursion avoidance - if (macro != null && !isLimitReached()) + if (macro != null && !isLimitReached(offsetBoundary, bufferStackPos, bufferPos, bufferStack )) for (int stackPos = bufferStackPos; stackPos >= 0; --stackPos) if (bufferData[stackPos] != null && bufferData[stackPos] instanceof MacroData @@ -2146,13 +2167,24 @@ abstract class BaseScanner implements IScanner { .getName())) { return false; } - return true; + return true; } /** * @return */ protected final boolean isLimitReached() { + return isLimitReached(offsetBoundary, bufferStackPos, bufferPos, bufferStack); + } + + /** + * @param offsetBoundary + * @param bufferStackPos + * @param bufferPos + * @param bufferStack + * @return + */ + protected final static boolean isLimitReached(int offsetBoundary, int bufferStackPos, int [] bufferPos, char [][]bufferStack ) { if (offsetBoundary == -1 || bufferStackPos != 0) return false; if (bufferPos[bufferStackPos] == offsetBoundary - 1) @@ -2165,6 +2197,7 @@ abstract class BaseScanner implements IScanner { return false; } + protected IToken scanString() { char[] buffer = bufferStack[bufferStackPos];