// Converts %XX and %uYYYY to the actual characters (I.e. Unesacpes any escape characters present in the URL) private String UnescapeURL(String url) { StringBuilder intermediate = StringBuilderCache.Acquire(url.Length); int Rindex = 0; // index into temp that gives the rest of the string to be processed int index; int braIndex = -1; int ketIndex = -1; braIndex = url.IndexOf('[', Rindex); if (braIndex != -1) { ketIndex = url.IndexOf(']', braIndex); } do { index = url.IndexOf('%', Rindex); if (index == -1) { intermediate = intermediate.Append(url, Rindex, (url.Length - Rindex)); break; } // if we hit a '%' in the middle of an IPv6 address, dont process that if (index > braIndex && index < ketIndex) { intermediate = intermediate.Append(url, Rindex, (ketIndex - Rindex + 1)); Rindex = ketIndex + 1; continue; } if (url.Length - index < 2) // Check that there is at least 1 char after the '%' { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } if (url[index + 1] == 'u' || url[index + 1] == 'U') { if (url.Length - index < 6) // example: "%u004d" is 6 chars long { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } // We have a unicode character specified in hex try { char c = (char)(Hex.ConvertHexDigit(url[index + 2]) << 12 | Hex.ConvertHexDigit(url[index + 3]) << 8 | Hex.ConvertHexDigit(url[index + 4]) << 4 | Hex.ConvertHexDigit(url[index + 5])); intermediate = intermediate.Append(url, Rindex, index - Rindex); intermediate = intermediate.Append(c); } catch (ArgumentException) // Hex.ConvertHexDigit can throw an "out of range" ArgumentException { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } Rindex = index + 6; //update the 'seen' length } else { // we have a hex character. if (url.Length - index < 3) // example: "%4d" is 3 chars long { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } try { char c = (char)(Hex.ConvertHexDigit(url[index + 1]) << 4 | Hex.ConvertHexDigit(url[index + 2])); intermediate = intermediate.Append(url, Rindex, index - Rindex); intermediate = intermediate.Append(c); } catch (ArgumentException) // Hex.ConvertHexDigit can throw an "out of range" ArgumentException { throw new ArgumentException(Environment.GetResourceString("Argument_InvalidUrl")); } Rindex = index + 3; // update the 'seen' length } }while (true); return(StringBuilderCache.GetStringAndRelease(intermediate)); }