// Parse the rest of a UTF-8 sequence within an encoded URI. private static int ParseRestOfUTF8(int utf8, string uri, ref int _index) { int index = _index; int size; int utf8Char; if ((utf8 & 0xE0) == 0xC0) { size = 1; utf8 &= 0x1F; } else if ((utf8 & 0xF0) == 0xE0) { size = 2; utf8 &= 0x0F; } else if ((utf8 & 0xF8) == 0xF0) { size = 3; utf8 &= 0x07; } else if ((utf8 & 0xFC) == 0xF8) { size = 4; utf8 &= 0x03; } else { // Invalid UTF-8 start character. throw new JScriptException(JSError.URIDecodeError); } while (size > 0) { if ((index + 2) >= uri.Length || uri[index] != '%' || !JSScanner.IsHexDigit(uri[index + 1]) || !JSScanner.IsHexDigit(uri[index + 2])) { throw new JScriptException(JSError.URIDecodeError); } utf8Char = (JSScanner.FromHex(uri[index + 1]) << 4) | JSScanner.FromHex(uri[index + 2]); if ((utf8Char & 0xC0) != 0x80) { // Invalid UTF-8 component character. throw new JScriptException(JSError.URIDecodeError); } index += 3; utf8 = (utf8 << 6) | (utf8Char & 0x3F); --size; } _index = index; if (utf8 < 0) { // Invalid UTF-8 character. throw new JScriptException(JSError.URIDecodeError); } return(utf8); }
public static string unescape(object str) { string s = Convert.ToString(str); StringBuilder builder = new StringBuilder(s.Length); int index = 0; char ch; while (index < s.Length) { ch = s[index++]; if (ch != '%') { builder.Append(ch); } else if ((index + 1) < s.Length && JSScanner.IsHexDigit(s[index]) && JSScanner.IsHexDigit(s[index + 1])) { ch = (char)((JSScanner.FromHex(s[index]) << 4) | JSScanner.FromHex(s[index + 1])); builder.Append(ch); index += 2; } else if ((index + 4) < s.Length && s[index] == 'u' && JSScanner.IsHexDigit(s[index + 1]) && JSScanner.IsHexDigit(s[index + 2]) && JSScanner.IsHexDigit(s[index + 3]) && JSScanner.IsHexDigit(s[index + 4])) { ch = (char)((JSScanner.FromHex(s[index + 1]) << 12) | (JSScanner.FromHex(s[index + 2]) << 8) | (JSScanner.FromHex(s[index + 3]) << 4) | JSScanner.FromHex(s[index + 4])); builder.Append(ch); index += 5; } else { builder.Append(ch); } } return(builder.ToString()); }
// Internal URI decoding logic. private static string InternalDecode(string uri, bool reserved) { StringBuilder builder = new StringBuilder(uri.Length); int index = 0; char ch; int utf8Char; int start; while (index < uri.Length) { ch = uri[index++]; if (ch != '%') { builder.Append(ch); } else if ((index + 1) >= uri.Length || !JSScanner.IsHexDigit(uri[index]) || !JSScanner.IsHexDigit(uri[index + 1])) { // Invalid hexadecimal sequence. throw new JScriptException(JSError.URIDecodeError); } else { start = index - 1; utf8Char = (JSScanner.FromHex(uri[index]) << 4) | JSScanner.FromHex(uri[index + 1]); index += 2; if (utf8Char >= 0x80) { // Parse the rest of the UTF-8 sequence. utf8Char = ParseRestOfUTF8 (utf8Char, uri, ref index); } if (utf8Char < 0x10000) { // Single-character. if (reserved && IsURIReserved((char)utf8Char)) { builder.Append(uri, start, index - start); } else { builder.Append((char)utf8Char); } } else if (utf8Char < 0x110000) { // Surrogate pair. utf8Char -= 0x10000; builder.Append((char)((utf8Char >> 10) + 0xD800)); builder.Append((char)((utf8Char & 0x3FF) + 0xDC00)); } else { // UTF-8 character is out of range. throw new JScriptException(JSError.URIDecodeError); } } } return(builder.ToString()); }