コード例 #1
0
        //
        // Will convert a host name into its idn equivalent
        //
        internal static unsafe string IdnEquivalent(char *hostname, int start, int end, ref bool allAscii, ref string bidiStrippedHost)
        {
            string idn = null;

            if (end <= start)
            {
                return(idn);
            }

            // indexes are validated

            int newPos = start;

            allAscii = true;

            while (newPos < end)
            {
                // check if only ascii chars
                // special case since idnmapping will not lowercase if only ascii present
                if (hostname[newPos] > '\x7F')
                {
                    allAscii = false;
                    break;
                }
                ++newPos;
            }

            if (allAscii)
            {
                // just lowercase for ascii
                string unescapedHostname = new string(hostname, start, end - start);
                return(unescapedHostname.ToLowerInvariant());
            }
            else
            {
                bidiStrippedHost = UriHelper.StripBidiControlCharacter(hostname, start, end - start);
                try
                {
                    string asciiForm = s_idnMapping.GetAscii(bidiStrippedHost);
                    if (ContainsCharactersUnsafeForNormalizedHost(asciiForm))
                    {
                        throw new UriFormatException(SR.net_uri_BadUnicodeHostForIdn);
                    }
                    return(asciiForm);
                }
                catch (ArgumentException)
                {
                    throw new UriFormatException(SR.net_uri_BadUnicodeHostForIdn);
                }
            }
        }
コード例 #2
0
        /// <summary>Converts a host name into its idn equivalent.</summary>
        internal static string IdnEquivalent(string hostname)
        {
            if (hostname.Length == 0)
            {
                return(hostname);
            }

            // check if only ascii chars
            // special case since idnmapping will not lowercase if only ascii present
            bool allAscii = true;

            foreach (char c in hostname)
            {
                if (c > 0x7F)
                {
                    allAscii = false;
                    break;
                }
            }

            if (allAscii)
            {
                // just lowercase for ascii
                return(hostname.ToLowerInvariant());
            }

            string bidiStrippedHost;

            unsafe
            {
                fixed(char *hostnamePtr = hostname)
                {
                    bidiStrippedHost = UriHelper.StripBidiControlCharacter(hostnamePtr, 0, hostname.Length);
                }
            }

            try
            {
                string asciiForm = s_idnMapping.GetAscii(bidiStrippedHost);
                if (ContainsCharactersUnsafeForNormalizedHost(asciiForm))
                {
                    throw new UriFormatException(SR.net_uri_BadUnicodeHostForIdn);
                }
                return(asciiForm);
            }
            catch (ArgumentException)
            {
                throw new UriFormatException(SR.net_uri_BadUnicodeHostForIdn);
            }
        }
コード例 #3
0
        internal static unsafe string UnicodeEquivalent(char *hostname, int start, int end, ref bool allAscii, ref bool atLeastOneValidIdn)
        {
            // hostname already validated
            allAscii           = true;
            atLeastOneValidIdn = false;
            string idn = null;

            if (end <= start)
            {
                return(idn);
            }

            string unescapedHostname = UriHelper.StripBidiControlCharacter(hostname, start, (end - start));

            string unicodeEqvlHost = null;
            int    curPos          = 0;
            int    newPos          = 0;
            int    length          = unescapedHostname.Length;
            bool   asciiLabel      = true;
            bool   foundAce        = false;
            bool   checkedAce      = false;
            bool   foundDot        = false;


            // We run a loop where for every label
            // a) if label is ascii and no ace then we lowercase it
            // b) if label is ascii and ace and not valid idn then just lowercase it
            // c) if label is ascii and ace and is valid idn then get its unicode eqvl
            // d) if label is unicode then clean it by running it through idnmapping
            do
            {
                asciiLabel = true;
                foundAce   = false;
                checkedAce = false;
                foundDot   = false;

                //find the dot or hit the end
                newPos = curPos;
                while (newPos < length)
                {
                    char c = unescapedHostname[newPos];
                    if (!checkedAce)
                    {
                        checkedAce = true;
                        if ((newPos + 3 < length) && (c == 'x') && IsIdnAce(unescapedHostname, newPos))
                        {
                            foundAce = true;
                        }
                    }
                    if (asciiLabel && (c > '\x7F'))
                    {
                        asciiLabel = false;
                        allAscii   = false;
                    }
                    if ((c == '.') || (c == '\u3002') ||    //IDEOGRAPHIC FULL STOP
                        (c == '\uFF0E') ||                  //FULLWIDTH FULL STOP
                        (c == '\uFF61'))                    //HALFWIDTH IDEOGRAPHIC FULL STOP
                    {
                        foundDot = true;
                        break;
                    }
                    ++newPos;
                }

                if (!asciiLabel)
                {
                    string asciiForm = unescapedHostname.Substring(curPos, newPos - curPos);
                    try
                    {
                        asciiForm = s_idnMapping.GetAscii(asciiForm);
                    }
                    catch (ArgumentException)
                    {
                        throw new UriFormatException(SR.net_uri_BadUnicodeHostForIdn);
                    }

                    unicodeEqvlHost += s_idnMapping.GetUnicode(asciiForm);
                    if (foundDot)
                    {
                        unicodeEqvlHost += ".";
                    }
                }
                else
                {
                    bool aceValid = false;
                    if (foundAce)
                    {
                        // check ace validity
                        try
                        {
                            unicodeEqvlHost += s_idnMapping.GetUnicode(unescapedHostname, curPos, newPos - curPos);
                            if (foundDot)
                            {
                                unicodeEqvlHost += ".";
                            }
                            aceValid           = true;
                            atLeastOneValidIdn = true;
                        }
                        catch (ArgumentException)
                        {
                            // not valid ace so treat it as a normal ascii label
                        }
                    }

                    if (!aceValid)
                    {
                        // for invalid aces we just lowercase the label
                        unicodeEqvlHost += unescapedHostname.Substring(curPos, newPos - curPos).ToLowerInvariant();
                        if (foundDot)
                        {
                            unicodeEqvlHost += ".";
                        }
                    }
                }

                curPos = newPos + (foundDot ? 1 : 0);
            } while (curPos < length);

            return(unicodeEqvlHost);
        }