private static bool encodeUnescaped(char c, bool fullUri) { if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z') || ('0' <= c && c <= '9')) { return(true); } if ("-_.!~*'()".IndexOf((char)c) >= 0) { return(true); } if (fullUri) { return(URI_DECODE_RESERVED.IndexOf((char)c) >= 0); } return(false); }
private static string decode(string str, bool fullUri) { char [] buf = null; int bufTop = 0; for (int k = 0, length = str.Length; k != length;) { char C = str [k]; if (C != '%') { if (buf != null) { buf [bufTop++] = C; } ++k; } else { if (buf == null) { // decode always compress so result can not be bigger then // str.length() buf = new char [length]; str.ToCharArray(0, k).CopyTo(buf, 0); bufTop = k; } int start = k; if (k + 3 > length) { throw Context.ReportRuntimeErrorById("msg.bad.uri"); } int B = unHex(str [k + 1], str [k + 2]); if (B < 0) { throw Context.ReportRuntimeErrorById("msg.bad.uri"); } k += 3; if ((B & 0x80) == 0) { C = (char)B; } else { // Decode UTF-8 sequence into ucs4Char and encode it into // UTF-16 int utf8Tail, ucs4Char, minUcs4Char; if ((B & 0xC0) == 0x80) { // First UTF-8 should be ouside 0x80..0xBF throw Context.ReportRuntimeErrorById("msg.bad.uri"); } else if ((B & 0x20) == 0) { utf8Tail = 1; ucs4Char = B & 0x1F; minUcs4Char = 0x80; } else if ((B & 0x10) == 0) { utf8Tail = 2; ucs4Char = B & 0x0F; minUcs4Char = 0x800; } else if ((B & 0x08) == 0) { utf8Tail = 3; ucs4Char = B & 0x07; minUcs4Char = 0x10000; } else if ((B & 0x04) == 0) { utf8Tail = 4; ucs4Char = B & 0x03; minUcs4Char = 0x200000; } else if ((B & 0x02) == 0) { utf8Tail = 5; ucs4Char = B & 0x01; minUcs4Char = 0x4000000; } else { // First UTF-8 can not be 0xFF or 0xFE throw Context.ReportRuntimeErrorById("msg.bad.uri"); } if (k + 3 * utf8Tail > length) { throw Context.ReportRuntimeErrorById("msg.bad.uri"); } for (int j = 0; j != utf8Tail; j++) { if (str [k] != '%') { throw Context.ReportRuntimeErrorById("msg.bad.uri"); } B = unHex(str [k + 1], str [k + 2]); if (B < 0 || (B & 0xC0) != 0x80) { throw Context.ReportRuntimeErrorById("msg.bad.uri"); } ucs4Char = (ucs4Char << 6) | (B & 0x3F); k += 3; } // Check for overlongs and other should-not-present codes if (ucs4Char < minUcs4Char || ucs4Char == 0xFFFE || ucs4Char == 0xFFFF) { ucs4Char = 0xFFFD; } if (ucs4Char >= 0x10000) { ucs4Char -= 0x10000; if (ucs4Char > 0xFFFFF) { throw Context.ReportRuntimeErrorById("msg.bad.uri"); } char H = (char)(((int)((uint)ucs4Char >> 10)) + 0xD800); C = (char)((ucs4Char & 0x3FF) + 0xDC00); buf [bufTop++] = H; } else { C = (char)ucs4Char; } } if (fullUri && URI_DECODE_RESERVED.IndexOf((char)C) >= 0) { for (int x = start; x != k; x++) { buf [bufTop++] = str [x]; } } else { buf [bufTop++] = C; } } } return((buf == null) ? str : new string (buf, 0, bufTop)); }