Unquote a git path that may contain escape sequences. Git quotes paths containing non-ASCII or special characters by wrapping them in double quotes and using octal or C-style escape sequences. This function reverses that encoding.
(input: &str)
| 52 | /// them in double quotes and using octal or C-style escape sequences. |
| 53 | /// This function reverses that encoding. |
| 54 | pub fn unquote_git_path(input: &str) -> String { |
| 55 | // PLACEHOLDER_CONTINUE |
| 56 | if !input.starts_with('"') || !input.ends_with('"') { |
| 57 | return input.to_string(); |
| 58 | } |
| 59 | |
| 60 | let body = &input[1..input.len() - 1]; |
| 61 | let mut bytes: Vec<u8> = Vec::with_capacity(body.len()); |
| 62 | let chars: Vec<char> = body.chars().collect(); |
| 63 | let mut i = 0; |
| 64 | |
| 65 | while i < chars.len() { |
| 66 | let ch = chars[i]; |
| 67 | if ch != '\\' { |
| 68 | let mut buf = [0u8; 4]; |
| 69 | let encoded = ch.encode_utf8(&mut buf); |
| 70 | bytes.extend_from_slice(encoded.as_bytes()); |
| 71 | i += 1; |
| 72 | continue; |
| 73 | } |
| 74 | |
| 75 | // Backslash escape |
| 76 | i += 1; |
| 77 | if i >= chars.len() { |
| 78 | bytes.push(b'\\'); |
| 79 | continue; |
| 80 | } |
| 81 | |
| 82 | let next = chars[i]; |
| 83 | |
| 84 | // Octal escape: \NNN where N is 0-7 |
| 85 | if next >= '0' && next <= '7' { |
| 86 | let start = i; |
| 87 | let mut end = i; |
| 88 | while end < chars.len() && end < start + 3 && chars[end] >= '0' && chars[end] <= '7' { |
| 89 | end += 1; |
| 90 | } |
| 91 | let octal_str: String = chars[start..end].iter().collect(); |
| 92 | if let Ok(val) = u8::from_str_radix(&octal_str, 8) { |
| 93 | bytes.push(val); |
| 94 | } else { |
| 95 | bytes.push(next as u8); |
| 96 | end = start + 1; |
| 97 | } |
| 98 | i = end; |
| 99 | continue; |
| 100 | } |
| 101 | |
| 102 | // Named escapes |
| 103 | let escaped: Option<u8> = match next { |
| 104 | 'n' => Some(b'\n'), |
| 105 | 'r' => Some(b'\r'), |
| 106 | 't' => Some(b'\t'), |
| 107 | 'b' => Some(0x08), // backspace |
| 108 | 'f' => Some(0x0C), // form feed |
| 109 | 'v' => Some(0x0B), // vertical tab |
| 110 | '\\' => Some(b'\\'), |
| 111 | '"' => Some(b'"'), |
no outgoing calls