We shouldn't escape non-special ASCII characters such as '@' or '~'. These are valid in a path name on POSIX systems, and may appear as part of a path in a GNU or Git style patch script. Escaping them into octal just obfuscates the user's intent, with no gain. When parsing an escaped octal sequence, we must parse no more than 3 digits. That is, "\1002" is actually "@2", not the Unicode character \u0202. Change-Id: I3a849a0d318e69b654f03fd559f5d7f99dd63e5c Signed-off-by: Shawn O. Pearce <spearce@spearce.org>tags/v0.9.1
public void testQuote_OctalAll() { | public void testQuote_OctalAll() { | ||||
assertQuote("\\001", "\1"); | assertQuote("\\001", "\1"); | ||||
assertQuote("\\176", "~"); | |||||
assertQuote("\\177", "\u007f"); | |||||
assertQuote("\\303\\277", "\u00ff"); // \u00ff in UTF-8 | assertQuote("\\303\\277", "\u00ff"); // \u00ff in UTF-8 | ||||
} | } | ||||
public void testQuote_Ang() { | public void testQuote_Ang() { | ||||
assertQuote("\\303\\205ngstr\\303\\266m", "\u00c5ngstr\u00f6m"); | assertQuote("\\303\\205ngstr\\303\\266m", "\u00c5ngstr\u00f6m"); | ||||
} | } | ||||
public void testQuoteAtAndNumber() { | |||||
assertSame("abc@2x.png", GIT_PATH.quote("abc@2x.png")); | |||||
assertDequote("abc@2x.png", "abc\\1002x.png"); | |||||
} | |||||
} | } |
for (int i = 'A'; i <= 'Z'; i++) | for (int i = 'A'; i <= 'Z'; i++) | ||||
quote[i] = 0; | quote[i] = 0; | ||||
quote[' '] = 0; | quote[' '] = 0; | ||||
quote['$'] = 0; | |||||
quote['%'] = 0; | |||||
quote['&'] = 0; | |||||
quote['*'] = 0; | |||||
quote['+'] = 0; | quote['+'] = 0; | ||||
quote[','] = 0; | quote[','] = 0; | ||||
quote['-'] = 0; | quote['-'] = 0; | ||||
quote['.'] = 0; | quote['.'] = 0; | ||||
quote['/'] = 0; | quote['/'] = 0; | ||||
quote[':'] = 0; | |||||
quote[';'] = 0; | |||||
quote['='] = 0; | quote['='] = 0; | ||||
quote['?'] = 0; | |||||
quote['@'] = 0; | |||||
quote['_'] = 0; | quote['_'] = 0; | ||||
quote['^'] = 0; | quote['^'] = 0; | ||||
quote['|'] = 0; | |||||
quote['~'] = 0; | |||||
quote['\u0007'] = 'a'; | quote['\u0007'] = 'a'; | ||||
quote['\b'] = 'b'; | quote['\b'] = 'b'; | ||||
case '2': | case '2': | ||||
case '3': { | case '3': { | ||||
int cp = in[inPtr - 1] - '0'; | int cp = in[inPtr - 1] - '0'; | ||||
while (inPtr < inEnd) { | |||||
for (int n = 1; n < 3 && inPtr < inEnd; n++) { | |||||
final byte c = in[inPtr]; | final byte c = in[inPtr]; | ||||
if ('0' <= c && c <= '7') { | if ('0' <= c && c <= '7') { | ||||
cp <<= 3; | cp <<= 3; |