Bug 574204 - Characters 0..31 are forbidden in windows

See https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
and sun.nio.fs.WindowsPathParser.isInvalidPathChar(char)

Change-Id: I9d3deb870dfc4bba79b0b42a23d19b71189e6da0
Signed-off-by: Joerg Kubitz <jkubitz-eclipse@gmx.de>
Reviewed-on: https://git.eclipse.org/r/c/platform/eclipse.platform.resources/+/181977
Tested-by: Platform Bot <platform-bot@eclipse.org>
Reviewed-by: Andrey Loskutov <loskutov@gmx.de>
diff --git a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/OS.java b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/OS.java
index ef0adcd..49be916 100644
--- a/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/OS.java
+++ b/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/OS.java
@@ -33,7 +33,13 @@
 		INSTALLED_PLATFORM = Platform.getOS();
 		if (INSTALLED_PLATFORM.equals(Platform.OS_WIN32)) {
 			//valid names and characters taken from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/naming_a_file.asp
-			INVALID_RESOURCE_CHARACTERS = new char[] {'\\', '/', ':', '*', '?', '"', '<', '>', '|'};
+			INVALID_RESOURCE_CHARACTERS = new char[] { '\\', '/', ':', '*', '?', '"', '<', '>', '|',
+					// Characters 0..31 are forbidden in windows
+					// See https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file
+					'\0', '\u0001', '\u0002', '\u0003', '\u0004', '\u0005', '\u0006', '\u0007', '\u0008', '\u0009',
+					'\n', '\u000b', '\u000c', '\r', '\u000e', '\u000f',
+					'\u0010', '\u0011', '\u0012', '\u0013', '\u0014', '\u0015', '\u0016', '\u0017', '\u0018', '\u0019',
+					'\u001a', '\u001b', '\u001c', '\u001d', '\u001e', '\u001f' };
 			INVALID_RESOURCE_BASENAMES = new String[] {"aux", "com1", "com2", "com3", "com4", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
 					"com5", "com6", "com7", "com8", "com9", "con", "lpt1", "lpt2", //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$
 					"lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", "nul", "prn"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
diff --git a/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/IWorkspaceTest.java b/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/IWorkspaceTest.java
index a9b5204..0872703 100644
--- a/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/IWorkspaceTest.java
+++ b/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/IWorkspaceTest.java
@@ -890,11 +890,29 @@
 			assertTrue("2.10", !getWorkspace().validateName("\\dsasf", IResource.FILE).isOK());
 			assertTrue("2.11", !getWorkspace().validateName("...", IResource.PROJECT).isOK());
 			assertTrue("2.12", !getWorkspace().validateName("foo.", IResource.FILE).isOK());
+			for (int i = 0; i <= 31; i++) {
+				assertTrue("2.13 Windows should NOT accept character #" + i,
+						!getWorkspace().validateName("anything" + ((char) i) + "something", IResource.FILE).isOK());
+			}
+			assertTrue("2.14 Windows should accept character #" + 32,
+					getWorkspace().validateName("anything" + ((char) 32) + "something", IResource.FILE).isOK());
+			assertTrue("2.15 Windows should NOT accept space at the end",
+					!getWorkspace().validateName("foo ", IResource.FILE).isOK());
+			assertTrue("2.16 Windows should accept space in the middle",
+					getWorkspace().validateName("fo o", IResource.FILE).isOK());
+			assertTrue("2.17 Windows should accept space in at the beginning",
+					getWorkspace().validateName(" foo", IResource.FILE).isOK());
 		} else {
 			//trailing dots are ok on other platforms
 			assertTrue("3.3", getWorkspace().validateName("...", IResource.FILE).isOK());
 			assertTrue("3.4", getWorkspace().validateName("....", IResource.PROJECT).isOK());
 			assertTrue("3.7", getWorkspace().validateName("abc.", IResource.FILE).isOK());
+			for (int i = 1; i <= 32; i++) {
+				assertTrue("3.8 Unix-style filesystems should accept character #" + i,
+						getWorkspace().validateName("anything" + ((char) i) + "something", IResource.FILE).isOK());
+			}
+			assertTrue("3.9 Unix-style filesystems should accept space at the end",
+					getWorkspace().validateName("foo ", IResource.FILE).isOK());
 		}
 		/* invalid characters on all platforms */
 		assertTrue("2.9", !getWorkspace().validateName("/dsasf", IResource.FILE).isOK());