Bug 306131 - [console] Null byte to stdout results in truncation of line

If interpretation of ASCII control characters is enabled handle null
bytes (\0) by simply filtering them out. This is useful because null
bytes can truncate console lines on some platforms and brings unexpected
results on copy text on most platforms.

Change-Id: Ic6a46c3eba4582c8f54fcd6735b8763738d47623
Signed-off-by: Paul Pazderski <paul-eclipse@ppazderski.de>
diff --git a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/IOConsoleTests.java b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/IOConsoleTests.java
index a90cad2..ae51f9f 100644
--- a/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/IOConsoleTests.java
+++ b/org.eclipse.debug.tests/src/org/eclipse/debug/tests/console/IOConsoleTests.java
@@ -612,6 +612,26 @@
 	}
 
 	/**
+	 * Test handling of <code>\0</code>.
+	 */
+	@Test
+	public void testNullByte() throws Exception {
+		final IOConsoleTestUtil c = getTestUtil("Test \\0");
+		c.getConsole().setHandleControlCharacters(true);
+		try (IOConsoleOutputStream err = c.getConsole().newOutputStream()) {
+			c.write("\u0000").verifyContent("");
+			c.write("abc\u0000123").verifyContent("abc123");
+			c.writeFast("\u0000", err).writeAndVerify("output");
+			c.write("\n\u0000x\u0000y\u0000z\u0000\u0000\u0000987", err).verifyContentByLine("xyz987", 1).verifyPartitions();
+			assertFalse(c.getDocument().get().contains("\u0000"));
+
+			c.clear();
+			c.writeFast("123").writeFast("\b\b\b").write("+\u0000+").verifyContent("++3").verifyPartitions();
+		}
+		closeConsole(c);
+	}
+
+	/**
 	 * Test larger number of partitions with pseudo random console content.
 	 */
 	@Test
diff --git a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java
index 6f593fe..0e448a6 100644
--- a/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java
+++ b/org.eclipse.ui.console/src/org/eclipse/ui/internal/console/IOConsolePartitioner.java
@@ -98,12 +98,12 @@
 	 * Pattern used to find supported ASCII control characters <b>except</b>
 	 * carriage return.
 	 */
-	private static final String CONTROL_CHARACTERS_PATTERN_STR = "(?:\b+|\u000b+|\f+)"; //$NON-NLS-1$
+	private static final String CONTROL_CHARACTERS_PATTERN_STR = "(?:\b+|\u0000+|\u000b+|\f+)"; //$NON-NLS-1$
 	/**
 	 * Pattern used to find supported ASCII control characters <b>including</b>
 	 * carriage return.
 	 */
-	private static final String CONTROL_CHARACTERS_WITH_CR_PATTERN_STR = "(?:\b+|\u000b+|\f+|\r+(?!\n))"; //$NON-NLS-1$
+	private static final String CONTROL_CHARACTERS_WITH_CR_PATTERN_STR = "(?:\b+|\u0000+|\u000b+|\f+|\r+(?!\n))"; //$NON-NLS-1$
 
 	/** The connected {@link IDocument} this partitioner manages. */
 	private IDocument document;
@@ -881,6 +881,7 @@
 						applyOutputToDocument(content.toString(), nextWriteOffset, replaceLength);
 						content.setLength(0);
 						replaceLength = 0;
+						nextWriteOffset = outputOffset;
 
 						final String controlCharacterMatch = controlCharacterMatcher.group();
 						final char controlCharacter = controlCharacterMatch.charAt(0);
@@ -949,6 +950,13 @@
 							partititonContent(pending.stream, vtab, 0, vtab.length());
 							break;
 
+						case 0:
+							// Do nothing for null bytes. The use of this is that a null byte which reach
+							// the IOConsoleViewer will truncate the line on some platforms and will disturb
+							// copying text on most platforms.
+							// This case should simply filter out any null bytes.
+							break;
+
 						default:
 							// should never happen as long as the used regex pattern is valid
 							log(IStatus.ERROR, "No implementation to handle control character 0x" //$NON-NLS-1$