Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 198776

Summary: Console view crashes when receiving strings ending with \r
Product: [Eclipse Project] Platform Reporter: Nils Hagge <nils.hagge>
Component: DebugAssignee: Platform-Debug-Inbox <platform-debug-inbox>
Status: RESOLVED DUPLICATE QA Contact:
Severity: critical    
Priority: P3 CC: cocoakevin, darin.eclipse, Tod_Creasey
Version: 3.3   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   
Whiteboard:

Description Nils Hagge CLA 2007-08-03 03:59:11 EDT
Build ID: I20070323-1616

Steps To Reproduce:
I write a plug-in that prints strings to a console view. This works fine until I print strings ending in one or more \r characters.


See log:
!ENTRY org.eclipse.ui 4 0 2007-08-02 16:03:00.531
!MESSAGE Unhandled event loop exception
!STACK 0
java.lang.ArrayIndexOutOfBoundsException
	at java.lang.System.arraycopy(Native Method)
	at org.eclipse.swt.custom.StyledTextRenderer.textChanging(StyledTextRenderer.java:1277)
	at org.eclipse.swt.custom.StyledText.handleTextChanging(StyledText.java:5329)
	at org.eclipse.swt.custom.StyledText$6.textChanging(StyledText.java:4767)
	at org.eclipse.ui.internal.console.ConsoleDocumentAdapter.documentAboutToBeChanged(ConsoleDocumentAdapter.java:298)
	at org.eclipse.jface.text.AbstractDocument.fireDocumentAboutToBeChanged(AbstractDocument.java:606)
	at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java:1072)
	at org.eclipse.jface.text.AbstractDocument.replace(AbstractDocument.java:1091)
	at org.eclipse.ui.internal.console.ConsoleDocument.replace(ConsoleDocument.java:83)
	at org.eclipse.ui.internal.console.ConsoleDocumentAdapter.replaceTextRange(ConsoleDocumentAdapter.java:254)
	at org.eclipse.swt.custom.StyledText.modifyContent(StyledText.java:5738)
	at org.eclipse.swt.custom.StyledText.sendKeyEvent(StyledText.java:6468)
	at org.eclipse.swt.custom.StyledText.doContent(StyledText.java:2148)
	at org.eclipse.swt.custom.StyledText.handleKey(StyledText.java:5021)
	at org.eclipse.swt.custom.StyledText.handleKeyDown(StyledText.java:5046)
	at org.eclipse.swt.custom.StyledText$7.handleEvent(StyledText.java:4790)
	at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:66)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:938)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:962)
	at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:947)
	at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:975)
	at org.eclipse.swt.widgets.Widget.sendKeyEvent(Widget.java:971)
	at org.eclipse.swt.widgets.Widget.wmChar(Widget.java:1285)
	at org.eclipse.swt.widgets.Control.WM_CHAR(Control.java:3770)
	at org.eclipse.swt.widgets.Control.windowProc(Control.java:3670)
	at org.eclipse.swt.widgets.Display.windowProc(Display.java:4342)
	at org.eclipse.swt.internal.win32.OS.DispatchMessageW(Native Method)
	at org.eclipse.swt.internal.win32.OS.DispatchMessage(OS.java:2226)
	at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3282)
	at org.eclipse.ui.internal.Workbench.runEventLoop(Workbench.java:2337)
	at org.eclipse.ui.internal.Workbench.runUI(Workbench.java:2301)
	at org.eclipse.ui.internal.Workbench.access$4(Workbench.java:2176)
	at org.eclipse.ui.internal.Workbench$4.run(Workbench.java:463)
	at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:289)
	at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:458)
	at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:149)
	at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:101)
	at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:146)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:106)
	at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:76)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:356)
	at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:171)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:476)
	at org.eclipse.equinox.launcher.Main.basicRun(Main.java:416)
	at org.eclipse.equinox.launcher.Main.run(Main.java:1141)
	at org.eclipse.equinox.launcher.Main.main(Main.java:1116)



2.
3.


More information:
I figured out that the error is related to the graphic update of the view. The view counts the number of lines that have to be updated.

I found the following method that performs this job: 

class org.eclipse.ui.internal.console.ConsoleDocumentAdapter {
  ....
   private int countNewLines(String string) {
		int count = 0;
		
		if (string.length() == 0) return 0;

		// work around to
		// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4994840
		// see bug 84641
		if (string.endsWith("\r")) { //$NON-NLS-1$
			int len = string.length();
			int index = len >= 2 ? len - 2 : 0;
			string = string.substring(0, index);
			count++;
		}
		
		int lastIndex = 0;
		int index = 0;
		
		Matcher matcher = pattern.matcher(string);
		
		while (matcher.find()) {
			index = matcher.start();
			
			if (index == 0)
				count++;
			else if (index!=string.length())
				count++;
			
			if (consoleWidth > 0) {
				int lineLen = index - lastIndex + 1;
				if (index == 0) lineLen += lengths[regionCount-1];
				count += lineLen/consoleWidth;
			}
			
			lastIndex = index;
		}
		return count;
	}
  ....

The comment that refers to the Pattern matcher bug is already suspicious, is not it? ;-)

From my point of view the problem is in the line:
int index = len >= 2 ? len - 2 : 0;

since this reduces the length of a string by _two_ characters. It should only truncate the last character! In my case e.g. a string ended in "hello\r\r\r". This meant that it was reduced to "hello\r" and the while loop just count one line.... And the problem with trailing \r is not even solved by this, but which on the other hand did not cause problems.

I suggest to replace

if (string.endsWith("\r")) { //$NON-NLS-1$
  int len = string.length();
  int index = len >= 2 ? len - 2 : 0;
  string = string.substring(0, index);
  count++;
}

by

while(string.endsWith("\r"))
{
  string = string.substring(0, string.length - 1);
  count++;
}

If the bug that the comment refers to is fixed as noted on the corresponding webpage, the whole code snippet can be erased anyway, since no more special treatment would be necessary.

Nils Hagge
Comment 1 Kevin Barnes CLA 2007-08-08 09:12:20 EDT
Debug team owns ConsoleDocumentAdapter.
Comment 2 Darin Wright CLA 2007-08-24 10:38:13 EDT

*** This bug has been marked as a duplicate of bug 176508 ***