Reject special Windows device names in ObjectChecker
If Windows rejection is enabled reject special device names like NUL and PRN, including NUL.txt. This prevents a tree that might be used on a Windows client from referencing a confusing name. Change-Id: Ic700ea8fa68724509e0357d4b758a41178c4d70c
This commit is contained in:
parent
5019471ccb
commit
ba0f89b421
|
@ -1039,6 +1039,7 @@ public void testValidPosixTree() throws CorruptObjectException {
|
|||
checkOneName("a<b>c:d|e");
|
||||
checkOneName("test ");
|
||||
checkOneName("test.");
|
||||
checkOneName("NUL");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1456,6 +1457,29 @@ public void testRejectDotAtEndOnWindows() {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRejectDevicesOnWindows() {
|
||||
checker.setSafeForWindows(true);
|
||||
|
||||
String[] bad = { "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3",
|
||||
"COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2",
|
||||
"LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9" };
|
||||
for (String b : bad) {
|
||||
try {
|
||||
checkOneName(b);
|
||||
fail("incorrectly accepted " + b);
|
||||
} catch (CorruptObjectException e) {
|
||||
assertEquals("invalid name '" + b + "'", e.getMessage());
|
||||
}
|
||||
try {
|
||||
checkOneName(b + ".txt");
|
||||
fail("incorrectly accepted " + b + ".txt");
|
||||
} catch (CorruptObjectException e) {
|
||||
assertEquals("invalid name '" + b + "'", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRejectInvalidWindowsCharacters() {
|
||||
checker.setSafeForWindows(true);
|
||||
|
|
|
@ -410,10 +410,68 @@ private void checkPathSegment(byte[] raw, int ptr, int end)
|
|||
}
|
||||
}
|
||||
|
||||
// Windows ignores space and dot at end of file name.
|
||||
if (windows && (raw[end - 1] == ' ' || raw[end - 1] == '.'))
|
||||
throw new CorruptObjectException("invalid name ends with '"
|
||||
+ ((char) raw[end - 1]) + "'");
|
||||
if (windows) {
|
||||
// Windows ignores space and dot at end of file name.
|
||||
if (raw[end - 1] == ' ' || raw[end - 1] == '.')
|
||||
throw new CorruptObjectException("invalid name ends with '"
|
||||
+ ((char) raw[end - 1]) + "'");
|
||||
if (end - ptr >= 3)
|
||||
checkNotWindowsDevice(raw, ptr, end);
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkNotWindowsDevice(byte[] raw, int ptr, int end)
|
||||
throws CorruptObjectException {
|
||||
switch (toLower(raw[ptr])) {
|
||||
case 'a': // AUX
|
||||
if (end - ptr >= 3
|
||||
&& toLower(raw[ptr + 1]) == 'u'
|
||||
&& toLower(raw[ptr + 2]) == 'x'
|
||||
&& (end - ptr == 3 || raw[ptr + 3] == '.'))
|
||||
throw new CorruptObjectException("invalid name 'AUX'");
|
||||
break;
|
||||
|
||||
case 'c': // CON, COM[1-9]
|
||||
if (end - ptr >= 3
|
||||
&& toLower(raw[ptr + 2]) == 'n'
|
||||
&& toLower(raw[ptr + 1]) == 'o'
|
||||
&& (end - ptr == 3 || raw[ptr + 3] == '.'))
|
||||
throw new CorruptObjectException("invalid name 'CON'");
|
||||
if (end - ptr >= 4
|
||||
&& toLower(raw[ptr + 2]) == 'm'
|
||||
&& toLower(raw[ptr + 1]) == 'o'
|
||||
&& isPositiveDigit(raw[ptr + 3])
|
||||
&& (end - ptr == 4 || raw[ptr + 4] == '.'))
|
||||
throw new CorruptObjectException("invalid name 'COM"
|
||||
+ ((char) raw[ptr + 3]) + "'");
|
||||
break;
|
||||
|
||||
case 'l': // LPT[1-9]
|
||||
if (end - ptr >= 4
|
||||
&& toLower(raw[ptr + 1]) == 'p'
|
||||
&& toLower(raw[ptr + 2]) == 't'
|
||||
&& isPositiveDigit(raw[ptr + 3])
|
||||
&& (end - ptr == 4 || raw[ptr + 4] == '.'))
|
||||
throw new CorruptObjectException("invalid name 'LPT"
|
||||
+ ((char) raw[ptr + 3]) + "'");
|
||||
break;
|
||||
|
||||
case 'n': // NUL
|
||||
if (end - ptr >= 3
|
||||
&& toLower(raw[ptr + 1]) == 'u'
|
||||
&& toLower(raw[ptr + 2]) == 'l'
|
||||
&& (end - ptr == 3 || raw[ptr + 3] == '.'))
|
||||
throw new CorruptObjectException("invalid name 'NUL'");
|
||||
break;
|
||||
|
||||
case 'p': // PRN
|
||||
if (end - ptr >= 3
|
||||
&& toLower(raw[ptr + 1]) == 'r'
|
||||
&& toLower(raw[ptr + 2]) == 'n'
|
||||
&& (end - ptr == 3 || raw[ptr + 3] == '.'))
|
||||
throw new CorruptObjectException("invalid name 'PRN'");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isInvalidOnWindows(byte c) {
|
||||
|
@ -446,6 +504,10 @@ private static char toLower(byte b) {
|
|||
return (char) b;
|
||||
}
|
||||
|
||||
private static boolean isPositiveDigit(byte b) {
|
||||
return '1' <= b && b <= '9';
|
||||
}
|
||||
|
||||
/**
|
||||
* Check a blob for errors.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue