Пример #1
0
        /* PunycodeDecode() converts Punycode to Unicode.  The input is  */
        /* represented as an array of ASCII code points, and the output   */
        /* will be represented as an array of Unicode code points.  The   */
        /* input_length is the number of code points in the input.  The   */
        /* output_length is an in/out argument: the caller passes in      */
        /* the maximum number of code points that it can receive, and     */
        /* on successful return it will contain the actual number of      */
        /* code points output.  The case_flags array needs room for at    */
        /* least output_length values, or it can be a null pointer if the */
        /* case information is not needed.  A nonzero flag suggests that  */
        /* the corresponding Unicode character be forced to uppercase     */
        /* by the caller (if possible), while zero suggests that it be    */
        /* forced to lowercase (if possible).  ASCII code points are      */
        /* output already in the proper case, but their flags will be set */
        /* appropriately so that applying the flags would be harmless.    */
        /* The return value can be any of the punycode_status values      */
        /* defined above; if not punycode_success, then output_length,    */
        /* output, and case_flags might contain garbage.  On success, the */
        /* decoder will never need to write an output_length greater than */
        /* input_length, because of how the encoding is defined.          */

        private static string PunycodeDecode(string ascii)
        {
            // 0 length strings aren't allowed
            if (ascii.Length == 0)
            {
                throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(ascii));
            }

            // Throw if we're too long
            if (ascii.Length > c_defaultNameLimit - (IsDot(ascii[ascii.Length - 1]) ? 0 : 1))
            {
                throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize,
                                                      c_defaultNameLimit - (IsDot(ascii[ascii.Length - 1]) ? 0 : 1)), nameof(ascii));
            }

            // output stringbuilder
            StringBuilder output = new StringBuilder(ascii.Length);

            // Dot searching
            int iNextDot            = 0;
            int iAfterLastDot       = 0;
            int iOutputAfterLastDot = 0;

            while (iNextDot < ascii.Length)
            {
                // Find end of this segment
                iNextDot = ascii.IndexOf('.', iAfterLastDot);
                if (iNextDot < 0 || iNextDot > ascii.Length)
                {
                    iNextDot = ascii.Length;
                }

                // Only allowed to have empty . section at end (www.microsoft.com.)
                if (iNextDot == iAfterLastDot)
                {
                    // Only allowed to have empty sections as trailing .
                    if (iNextDot != ascii.Length)
                    {
                        throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(ascii));
                    }

                    // Last dot, stop
                    break;
                }

                // In either case it can't be bigger than segment size
                if (iNextDot - iAfterLastDot > c_labelLimit)
                {
                    throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(ascii));
                }

                // See if this section's ASCII or ACE
                if (ascii.Length < c_strAcePrefix.Length + iAfterLastDot ||
                    !ascii.Substring(iAfterLastDot, c_strAcePrefix.Length).Equals(c_strAcePrefix, StringComparison.OrdinalIgnoreCase))
                {
                    // Its ASCII, copy it
                    output.Append(ascii.Substring(iAfterLastDot, iNextDot - iAfterLastDot));
                }
                else
                {
                    // Not ASCII, bump up iAfterLastDot to be after ACE Prefix
                    iAfterLastDot += c_strAcePrefix.Length;

                    // Get number of basic code points (where delimiter is)
                    // numBasicCodePoints < 0 if there're no basic code points
                    int iTemp = ascii.LastIndexOf(c_delimiter, iNextDot - 1);

                    // Trailing - not allowed
                    if (iTemp == iNextDot - 1)
                    {
                        throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
                    }

                    int numBasicCodePoints;
                    if (iTemp <= iAfterLastDot)
                    {
                        numBasicCodePoints = 0;
                    }
                    else
                    {
                        numBasicCodePoints = iTemp - iAfterLastDot;

                        // Copy all the basic code points, making sure they're all in the allowed range,
                        // and losing the casing for all of them.
                        for (int copyAscii = iAfterLastDot; copyAscii < iAfterLastDot + numBasicCodePoints; copyAscii++)
                        {
                            // Make sure we don't allow unicode in the ascii part
                            if (ascii[copyAscii] > 0x7f)
                            {
                                throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
                            }

                            // When appending make sure they get lower cased
                            output.Append((char)(ascii[copyAscii] >= 'A' && ascii[copyAscii] <= 'Z' ? ascii[copyAscii] - 'A' + 'a' : ascii[copyAscii]));
                        }
                    }

                    // Get ready for main loop.  Start at beginning if we didn't have any
                    // basic code points, otherwise start after the -.
                    // asciiIndex will be next character to read from ascii
                    int asciiIndex = iAfterLastDot + (numBasicCodePoints > 0 ? numBasicCodePoints + 1 : 0);

                    // initialize our state
                    int n    = c_initialN;
                    int bias = c_initialBias;
                    int i    = 0;

                    int w, k;

                    // no Supplementary characters yet
                    int numSurrogatePairs = 0;

                    // Main loop, read rest of ascii
                    while (asciiIndex < iNextDot)
                    {
                        /* Decode a generalized variable-length integer into delta,  */
                        /* which gets added to i.  The overflow checking is easier   */
                        /* if we increase i as we go, then subtract off its starting */
                        /* value at the end to obtain delta.                         */
                        int oldi = i;

                        for (w = 1, k = c_punycodeBase;  ; k += c_punycodeBase)
                        {
                            // Check to make sure we aren't overrunning our ascii string
                            if (asciiIndex >= iNextDot)
                            {
                                throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
                            }

                            // decode the digit from the next char
                            int digit = DecodeDigit(ascii[asciiIndex++]);

                            Debug.Assert(w > 0, "[IdnMapping.punycode_decode]Expected w > 0");
                            if (digit > (c_maxint - i) / w)
                            {
                                throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
                            }

                            i += (int)(digit * w);
                            int t = k <= bias ? c_tmin : k >= bias + c_tmax ? c_tmax : k - bias;
                            if (digit < t)
                            {
                                break;
                            }
                            Debug.Assert(c_punycodeBase != t, "[IdnMapping.punycode_decode]Expected t != c_punycodeBase (36)");
                            if (w > c_maxint / (c_punycodeBase - t))
                            {
                                throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
                            }
                            w *= (c_punycodeBase - t);
                        }

                        bias = Adapt(i - oldi, (output.Length - iOutputAfterLastDot - numSurrogatePairs) + 1, oldi == 0);

                        /* i was supposed to wrap around from output.Length to 0,   */
                        /* incrementing n each time, so we'll fix that now: */
                        Debug.Assert((output.Length - iOutputAfterLastDot - numSurrogatePairs) + 1 > 0,
                                     "[IdnMapping.punycode_decode]Expected to have added > 0 characters this segment");
                        if (i / ((output.Length - iOutputAfterLastDot - numSurrogatePairs) + 1) > c_maxint - n)
                        {
                            throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
                        }
                        n += (int)(i / (output.Length - iOutputAfterLastDot - numSurrogatePairs + 1));
                        i %= (output.Length - iOutputAfterLastDot - numSurrogatePairs + 1);

                        // Make sure n is legal
                        if ((n < 0 || n > 0x10ffff) || (n >= 0xD800 && n <= 0xDFFF))
                        {
                            throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
                        }

                        // insert n at position i of the output:  Really tricky if we have surrogates
                        int    iUseInsertLocation;
                        String strTemp = Char.ConvertFromUtf32(n);

                        // If we have supplimentary characters
                        if (numSurrogatePairs > 0)
                        {
                            // Hard way, we have supplimentary characters
                            int iCount;
                            for (iCount = i, iUseInsertLocation = iOutputAfterLastDot; iCount > 0; iCount--, iUseInsertLocation++)
                            {
                                // If its a surrogate, we have to go one more
                                if (iUseInsertLocation >= output.Length)
                                {
                                    throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(ascii));
                                }
                                if (Char.IsSurrogate(output[iUseInsertLocation]))
                                {
                                    iUseInsertLocation++;
                                }
                            }
                        }
                        else
                        {
                            // No Supplementary chars yet, just add i
                            iUseInsertLocation = iOutputAfterLastDot + i;
                        }

                        // Insert it
                        output.Insert(iUseInsertLocation, strTemp);

                        // If it was a surrogate increment our counter
                        if (IsSupplementary(n))
                        {
                            numSurrogatePairs++;
                        }

                        // Index gets updated
                        i++;
                    }

                    // Do BIDI testing
                    bool bRightToLeft = false;

                    // Check for RTL.  If right-to-left, then 1st & last chars must be RTL
                    BidiCategory eBidi = CharUnicodeInfo.GetBidiCategory(output.ToString(), iOutputAfterLastDot);
                    if (eBidi == BidiCategory.RightToLeft || eBidi == BidiCategory.RightToLeftArabic)
                    {
                        // It has to be right to left.
                        bRightToLeft = true;
                    }

                    // Check the rest of them to make sure RTL/LTR is consistent
                    for (int iTest = iOutputAfterLastDot; iTest < output.Length; iTest++)
                    {
                        // This might happen if we run into a pair
                        if (Char.IsLowSurrogate(output.ToString(), iTest))
                        {
                            continue;
                        }

                        // Check to see if its LTR
                        eBidi = CharUnicodeInfo.GetBidiCategory(output.ToString(), iTest);
                        if ((bRightToLeft && eBidi == BidiCategory.LeftToRight) ||
                            (!bRightToLeft && (eBidi == BidiCategory.RightToLeft || eBidi == BidiCategory.RightToLeftArabic)))
                        {
                            throw new ArgumentException(SR.Argument_IdnBadBidi, nameof(ascii));
                        }
                    }

                    // Its also a requirement that the last one be RTL if 1st is RTL
                    if (bRightToLeft && eBidi != BidiCategory.RightToLeft && eBidi != BidiCategory.RightToLeftArabic)
                    {
                        // Oops, last wasn't RTL, last should be RTL if first is RTL
                        throw new ArgumentException(SR.Argument_IdnBadBidi, nameof(ascii));
                    }
                }

                // See if this label was too long
                if (iNextDot - iAfterLastDot > c_labelLimit)
                {
                    throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(ascii));
                }

                // Done with this segment, add dot if necessary
                if (iNextDot != ascii.Length)
                {
                    output.Append('.');
                }

                iAfterLastDot       = iNextDot + 1;
                iOutputAfterLastDot = output.Length;
            }

            // Throw if we're too long
            if (output.Length > c_defaultNameLimit - (IsDot(output[output.Length - 1]) ? 0 : 1))
            {
                throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize, c_defaultNameLimit - (IsDot(output[output.Length - 1]) ? 0 : 1)), nameof(ascii));
            }

            // Return our output string
            return(output.ToString());
        }
Пример #2
0
        private static string punycode_decode(string ascii)
        {
            if (ascii.Length == 0)
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
            }
            int    length1 = ascii.Length;
            int    num1    = (int)byte.MaxValue;
            string str1    = ascii;
            int    index1  = str1.Length - 1;
            int    num2    = IdnMapping.IsDot(str1[index1]) ? 0 : 1;
            int    num3    = num1 - num2;

            if (length1 > num3)
            {
                string   key      = "Argument_IdnBadNameSize";
                object[] objArray = new object[1];
                int      index2   = 0;
                int      num4     = (int)byte.MaxValue;
                string   str2     = ascii;
                int      index3   = str2.Length - 1;
                int      num5     = IdnMapping.IsDot(str2[index3]) ? 0 : 1;
                // ISSUE: variable of a boxed type
                __Boxed <int> local = (ValueType)(num4 - num5);
                objArray[index2] = (object)local;
                throw new ArgumentException(Environment.GetResourceString(key, objArray), "ascii");
            }
            StringBuilder stringBuilder1 = new StringBuilder(ascii.Length);
            int           num6           = 0;
            int           startIndex     = 0;
            int           index4         = 0;

            while (num6 < ascii.Length)
            {
                num6 = ascii.IndexOf('.', startIndex);
                if (num6 < 0 || num6 > ascii.Length)
                {
                    num6 = ascii.Length;
                }
                if (num6 == startIndex)
                {
                    if (num6 != ascii.Length)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
                    }
                    break;
                }
                if (num6 - startIndex > 63)
                {
                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
                }
                if (ascii.Length < "xn--".Length + startIndex || !ascii.Substring(startIndex, "xn--".Length).Equals("xn--", StringComparison.OrdinalIgnoreCase))
                {
                    stringBuilder1.Append(ascii.Substring(startIndex, num6 - startIndex));
                }
                else
                {
                    startIndex += "xn--".Length;
                    int num4 = ascii.LastIndexOf('-', num6 - 1);
                    if (num4 == num6 - 1)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                    }
                    int num5;
                    if (num4 <= startIndex)
                    {
                        num5 = 0;
                    }
                    else
                    {
                        num5 = num4 - startIndex;
                        for (int index2 = startIndex; index2 < startIndex + num5; ++index2)
                        {
                            if ((int)ascii[index2] > (int)sbyte.MaxValue)
                            {
                                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                            }
                            stringBuilder1.Append((int)ascii[index2] < 65 || (int)ascii[index2] > 90 ? ascii[index2] : (char)((int)ascii[index2] - 65 + 97));
                        }
                    }
                    int num7  = startIndex + (num5 > 0 ? num5 + 1 : 0);
                    int num8  = 128;
                    int num9  = 72;
                    int num10 = 0;
                    int num11 = 0;
label_49:
                    while (num7 < num6)
                    {
                        int num12 = num10;
                        int num13 = 1;
                        int num14 = 36;
                        while (num7 < num6)
                        {
                            int num15 = IdnMapping.decode_digit(ascii[num7++]);
                            if (num15 > (134217727 - num10) / num13)
                            {
                                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                            }
                            num10 += num15 * num13;
                            int num16 = num14 <= num9 ? 1 : (num14 >= num9 + 26 ? 26 : num14 - num9);
                            if (num15 >= num16)
                            {
                                if (num13 > 134217727 / (36 - num16))
                                {
                                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                }
                                num13 *= 36 - num16;
                                num14 += 36;
                            }
                            else
                            {
                                num9 = IdnMapping.adapt(num10 - num12, stringBuilder1.Length - index4 - num11 + 1, num12 == 0);
                                if (num10 / (stringBuilder1.Length - index4 - num11 + 1) > 134217727 - num8)
                                {
                                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                }
                                num8 += num10 / (stringBuilder1.Length - index4 - num11 + 1);
                                int num17 = num10 % (stringBuilder1.Length - index4 - num11 + 1);
                                if (num8 < 0 || num8 > 1114111 || num8 >= 55296 && num8 <= 57343)
                                {
                                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                }
                                string str2 = char.ConvertFromUtf32(num8);
                                int    index2;
                                if (num11 > 0)
                                {
                                    int num18 = num17;
                                    index2 = index4;
                                    while (num18 > 0)
                                    {
                                        if (index2 >= stringBuilder1.Length)
                                        {
                                            throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                        }
                                        if (char.IsSurrogate(stringBuilder1[index2]))
                                        {
                                            ++index2;
                                        }
                                        --num18;
                                        ++index2;
                                    }
                                }
                                else
                                {
                                    index2 = index4 + num17;
                                }
                                stringBuilder1.Insert(index2, str2);
                                if (IdnMapping.IsSupplementary(num8))
                                {
                                    ++num11;
                                }
                                num10 = num17 + 1;
                                goto label_49;
                            }
                        }
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                    }
                    bool         flag         = false;
                    BidiCategory bidiCategory = CharUnicodeInfo.GetBidiCategory(stringBuilder1.ToString(), index4);
                    switch (bidiCategory)
                    {
                    case BidiCategory.RightToLeft:
                    case BidiCategory.RightToLeftArabic:
                        flag = true;
                        break;
                    }
                    for (int index2 = index4; index2 < stringBuilder1.Length; ++index2)
                    {
                        if (!char.IsLowSurrogate(stringBuilder1.ToString(), index2))
                        {
                            bidiCategory = CharUnicodeInfo.GetBidiCategory(stringBuilder1.ToString(), index2);
                            if (flag && bidiCategory == BidiCategory.LeftToRight || !flag && (bidiCategory == BidiCategory.RightToLeft || bidiCategory == BidiCategory.RightToLeftArabic))
                            {
                                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "ascii");
                            }
                        }
                    }
                    if (flag && bidiCategory != BidiCategory.RightToLeft && bidiCategory != BidiCategory.RightToLeftArabic)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "ascii");
                    }
                }
                if (num6 - startIndex > 63)
                {
                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
                }
                if (num6 != ascii.Length)
                {
                    stringBuilder1.Append('.');
                }
                startIndex = num6 + 1;
                index4     = stringBuilder1.Length;
            }
            int           length2        = stringBuilder1.Length;
            int           num19          = (int)byte.MaxValue;
            StringBuilder stringBuilder2 = stringBuilder1;
            int           index5         = stringBuilder2.Length - 1;
            int           num20          = IdnMapping.IsDot(stringBuilder2[index5]) ? 0 : 1;
            int           num21          = num19 - num20;

            if (length2 > num21)
            {
                string        key            = "Argument_IdnBadNameSize";
                object[]      objArray       = new object[1];
                int           index2         = 0;
                int           num4           = (int)byte.MaxValue;
                StringBuilder stringBuilder3 = stringBuilder1;
                int           index3         = stringBuilder3.Length - 1;
                int           num5           = IdnMapping.IsDot(stringBuilder3[index3]) ? 0 : 1;
                // ISSUE: variable of a boxed type
                __Boxed <int> local = (ValueType)(num4 - num5);
                objArray[index2] = (object)local;
                throw new ArgumentException(Environment.GetResourceString(key, objArray), "ascii");
            }
            return(stringBuilder1.ToString());
        }
Пример #3
0
        /* PunycodeEncode() converts Unicode to Punycode.  The input     */
        /* is represented as an array of Unicode code points (not code    */
        /* units; surrogate pairs are not allowed), and the output        */
        /* will be represented as an array of ASCII code points.  The     */
        /* output string is *not* null-terminated; it will contain        */
        /* zeros if and only if the input contains zeros.  (Of course     */
        /* the caller can leave room for a terminator and add one if      */
        /* needed.)  The input_length is the number of code points in     */
        /* the input.  The output_length is an in/out argument: the       */
        /* caller passes in the maximum number of code points that it     */

        /* can receive, and on successful return it will contain the      */
        /* number of code points actually output.  The case_flags array   */
        /* holds input_length boolean values, where nonzero suggests that */
        /* the corresponding Unicode character be forced to uppercase     */
        /* after being decoded (if possible), and zero suggests that      */
        /* it be forced to lowercase (if possible).  ASCII code points    */
        /* are encoded literally, except that ASCII letters are forced    */
        /* to uppercase or lowercase according to the corresponding       */
        /* uppercase flags.  If case_flags is a null pointer then ASCII   */
        /* letters are left as they are, and other code points are        */
        /* treated as if their uppercase flags were zero.  The return     */
        /* value can be any of the punycode_status values defined above   */
        /* except punycode_bad_input; if not punycode_success, then       */
        /* output_size and output might contain garbage.                  */
        static string PunycodeEncode(string unicode)
        {
            // 0 length strings aren't allowed
            if (unicode.Length == 0)
            {
                throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
            }

            StringBuilder output              = new StringBuilder(unicode.Length);
            int           iNextDot            = 0;
            int           iAfterLastDot       = 0;
            int           iOutputAfterLastDot = 0;

            // Find the next dot
            while (iNextDot < unicode.Length)
            {
                // Find end of this segment
                iNextDot = unicode.IndexOfAny(c_Dots, iAfterLastDot);
                Contract.Assert(iNextDot <= unicode.Length, "[IdnMapping.punycode_encode]IndexOfAny is broken");
                if (iNextDot < 0)
                {
                    iNextDot = unicode.Length;
                }

                // Only allowed to have empty . section at end (www.microsoft.com.)
                if (iNextDot == iAfterLastDot)
                {
                    // Only allowed to have empty sections as trailing .
                    if (iNextDot != unicode.Length)
                    {
                        throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
                    }
                    // Last dot, stop
                    break;
                }

                // We'll need an Ace prefix
                output.Append(c_strAcePrefix);

                // Everything resets every segment.
                bool bRightToLeft = false;

                // Check for RTL.  If right-to-left, then 1st & last chars must be RTL
                BidiCategory eBidi = CharUnicodeInfo.GetBidiCategory(unicode, iAfterLastDot);
                if (eBidi == BidiCategory.RightToLeft || eBidi == BidiCategory.RightToLeftArabic)
                {
                    // It has to be right to left.
                    bRightToLeft = true;

                    // Check last char
                    int iTest = iNextDot - 1;
                    if (Char.IsLowSurrogate(unicode, iTest))
                    {
                        iTest--;
                    }

                    eBidi = CharUnicodeInfo.GetBidiCategory(unicode, iTest);
                    if (eBidi != BidiCategory.RightToLeft && eBidi != BidiCategory.RightToLeftArabic)
                    {
                        // Oops, last wasn't RTL, last should be RTL if first is RTL
                        throw new ArgumentException(SR.Argument_IdnBadBidi, nameof(unicode));
                    }
                }

                // Handle the basic code points
                int basicCount;
                int numProcessed = 0;           // Num code points that have been processed so far (this segment)
                for (basicCount = iAfterLastDot; basicCount < iNextDot; basicCount++)
                {
                    // Can't be lonely surrogate because it would've thrown in normalization
                    Debug.Assert(Char.IsLowSurrogate(unicode, basicCount) == false, "[IdnMapping.punycode_encode]Unexpected low surrogate");

                    // Double check our bidi rules
                    BidiCategory testBidi = CharUnicodeInfo.GetBidiCategory(unicode, basicCount);

                    // If we're RTL, we can't have LTR chars
                    if (bRightToLeft && testBidi == BidiCategory.LeftToRight)
                    {
                        // Oops, throw error
                        throw new ArgumentException(SR.Argument_IdnBadBidi, nameof(unicode));
                    }

                    // If we're not RTL we can't have RTL chars
                    if (!bRightToLeft && (testBidi == BidiCategory.RightToLeft || testBidi == BidiCategory.RightToLeftArabic))
                    {
                        // Oops, throw error
                        throw new ArgumentException(SR.Argument_IdnBadBidi, nameof(unicode));
                    }

                    // If its basic then add it
                    if (Basic(unicode[basicCount]))
                    {
                        output.Append(EncodeBasic(unicode[basicCount]));
                        numProcessed++;
                    }
                    // If its a surrogate, skip the next since our bidi category tester doesn't handle it.
                    else if (Char.IsSurrogatePair(unicode, basicCount))
                    {
                        basicCount++;
                    }
                }

                int numBasicCodePoints = numProcessed;     // number of basic code points

                // Stop if we ONLY had basic code points
                if (numBasicCodePoints == iNextDot - iAfterLastDot)
                {
                    // Get rid of xn-- and this segments done
                    output.Remove(iOutputAfterLastDot, c_strAcePrefix.Length);
                }
                else
                {
                    // If it has some non-basic code points the input cannot start with xn--
                    if (unicode.Length - iAfterLastDot >= c_strAcePrefix.Length &&
                        unicode.Substring(iAfterLastDot, c_strAcePrefix.Length).Equals(
                            c_strAcePrefix, StringComparison.OrdinalIgnoreCase))
                    {
                        throw new ArgumentException(SR.Argument_IdnBadPunycode, nameof(unicode));
                    }

                    // Need to do ACE encoding
                    int numSurrogatePairs = 0;            // number of surrogate pairs so far

                    // Add a delimiter (-) if we had any basic code points (between basic and encoded pieces)
                    if (numBasicCodePoints > 0)
                    {
                        output.Append(c_delimiter);
                    }

                    // Initialize the state
                    int n     = c_initialN;
                    int delta = 0;
                    int bias  = c_initialBias;

                    // Main loop
                    while (numProcessed < (iNextDot - iAfterLastDot))
                    {
                        /* All non-basic code points < n have been     */
                        /* handled already.  Find the next larger one: */
                        int j;
                        int m;
                        int test = 0;
                        for (m = c_maxint, j = iAfterLastDot;
                             j < iNextDot;
                             j += IsSupplementary(test) ? 2 : 1)
                        {
                            test = Char.ConvertToUtf32(unicode, j);
                            if (test >= n && test < m)
                            {
                                m = test;
                            }
                        }

                        /* Increase delta enough to advance the decoder's    */
                        /* <n,i> state to <m,0>, but guard against overflow: */
                        delta += (int)((m - n) * ((numProcessed - numSurrogatePairs) + 1));
                        Debug.Assert(delta > 0, "[IdnMapping.cs]1 punycode_encode - delta overflowed int");
                        n = m;

                        for (j = iAfterLastDot; j < iNextDot; j += IsSupplementary(test) ? 2 : 1)
                        {
                            // Make sure we're aware of surrogates
                            test = Char.ConvertToUtf32(unicode, j);

                            // Adjust for character position (only the chars in our string already, some
                            // haven't been processed.

                            if (test < n)
                            {
                                delta++;
                                Contract.Assert(delta > 0, "[IdnMapping.cs]2 punycode_encode - delta overflowed int");
                            }

                            if (test == n)
                            {
                                // Represent delta as a generalized variable-length integer:
                                int q, k;
                                for (q = delta, k = c_punycodeBase;  ; k += c_punycodeBase)
                                {
                                    int t = k <= bias ? c_tmin : k >= bias + c_tmax ? c_tmax : k - bias;
                                    if (q < t)
                                    {
                                        break;
                                    }
                                    Debug.Assert(c_punycodeBase != t, "[IdnMapping.punycode_encode]Expected c_punycodeBase (36) to be != t");
                                    output.Append(EncodeDigit(t + (q - t) % (c_punycodeBase - t)));
                                    q = (q - t) / (c_punycodeBase - t);
                                }

                                output.Append(EncodeDigit(q));
                                bias  = Adapt(delta, (numProcessed - numSurrogatePairs) + 1, numProcessed == numBasicCodePoints);
                                delta = 0;
                                numProcessed++;

                                if (IsSupplementary(m))
                                {
                                    numProcessed++;
                                    numSurrogatePairs++;
                                }
                            }
                        }
                        ++delta;
                        ++n;
                        Debug.Assert(delta > 0, "[IdnMapping.cs]3 punycode_encode - delta overflowed int");
                    }
                }

                // Make sure its not too big
                if (output.Length - iOutputAfterLastDot > c_labelLimit)
                {
                    throw new ArgumentException(SR.Argument_IdnBadLabelSize, nameof(unicode));
                }

                // Done with this segment, add dot if necessary
                if (iNextDot != unicode.Length)
                {
                    output.Append('.');
                }

                iAfterLastDot       = iNextDot + 1;
                iOutputAfterLastDot = output.Length;
            }

            // Throw if we're too long
            if (output.Length > c_defaultNameLimit - (IsDot(unicode[unicode.Length - 1]) ? 0 : 1))
            {
                throw new ArgumentException(SR.Format(SR.Argument_IdnBadNameSize,
                                                      c_defaultNameLimit - (IsDot(unicode[unicode.Length - 1]) ? 0 : 1)), nameof(unicode));
            }
            // Return our output string
            return(output.ToString());
        }
Пример #4
0
        private static string punycode_encode(string unicode)
        {
            if (unicode.Length == 0)
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "unicode");
            }
            StringBuilder stringBuilder = new StringBuilder(unicode.Length);
            int           num1          = 0;
            int           num2          = 0;
            int           startIndex    = 0;

            while (num1 < unicode.Length)
            {
                num1 = unicode.IndexOfAny(IdnMapping.M_Dots, num2);
                if (num1 < 0)
                {
                    num1 = unicode.Length;
                }
                if (num1 == num2)
                {
                    if (num1 != unicode.Length)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "unicode");
                    }
                    break;
                }
                stringBuilder.Append("xn--");
                bool flag = false;
                switch (CharUnicodeInfo.GetBidiCategory(unicode, num2))
                {
                case BidiCategory.RightToLeft:
                case BidiCategory.RightToLeftArabic:
                    flag = true;
                    int index1 = num1 - 1;
                    if (char.IsLowSurrogate(unicode, index1))
                    {
                        --index1;
                    }
                    switch (CharUnicodeInfo.GetBidiCategory(unicode, index1))
                    {
                    case BidiCategory.RightToLeft:
                    case BidiCategory.RightToLeftArabic:
                        break;

                    default:
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "unicode");
                    }
                }
                int num3 = 0;
                for (int index2 = num2; index2 < num1; ++index2)
                {
                    BidiCategory bidiCategory = CharUnicodeInfo.GetBidiCategory(unicode, index2);
                    if (flag && bidiCategory == BidiCategory.LeftToRight)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "unicode");
                    }
                    if (!flag && (bidiCategory == BidiCategory.RightToLeft || bidiCategory == BidiCategory.RightToLeftArabic))
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "unicode");
                    }
                    if (IdnMapping.basic((uint)unicode[index2]))
                    {
                        stringBuilder.Append(IdnMapping.encode_basic(unicode[index2]));
                        ++num3;
                    }
                    else if (char.IsSurrogatePair(unicode, index2))
                    {
                        ++index2;
                    }
                }
                int num4 = num3;
                if (num4 == num1 - num2)
                {
                    stringBuilder.Remove(startIndex, "xn--".Length);
                }
                else
                {
                    if (unicode.Length - num2 >= "xn--".Length && unicode.Substring(num2, "xn--".Length).Equals("xn--", StringComparison.OrdinalIgnoreCase))
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "unicode");
                    }
                    int num5 = 0;
                    if (num4 > 0)
                    {
                        stringBuilder.Append('-');
                    }
                    int num6 = 128;
                    int num7 = 0;
                    int num8 = 72;
                    while (num3 < num1 - num2)
                    {
                        int cTest  = 134217727;
                        int index2 = num2;
                        while (index2 < num1)
                        {
                            int utf32 = char.ConvertToUtf32(unicode, index2);
                            if (utf32 >= num6 && utf32 < cTest)
                            {
                                cTest = utf32;
                            }
                            index2 += IdnMapping.IsSupplementary(utf32) ? 2 : 1;
                        }
                        int delta  = num7 + (cTest - num6) * (num3 - num5 + 1);
                        int num9   = cTest;
                        int index3 = num2;
                        while (index3 < num1)
                        {
                            int utf32 = char.ConvertToUtf32(unicode, index3);
                            if (utf32 < num9)
                            {
                                ++delta;
                            }
                            if (utf32 == num9)
                            {
                                int d     = delta;
                                int num10 = 36;
                                while (true)
                                {
                                    int num11 = num10 <= num8 ? 1 : (num10 >= num8 + 26 ? 26 : num10 - num8);
                                    if (d >= num11)
                                    {
                                        stringBuilder.Append(IdnMapping.encode_digit(num11 + (d - num11) % (36 - num11)));
                                        d      = (d - num11) / (36 - num11);
                                        num10 += 36;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                stringBuilder.Append(IdnMapping.encode_digit(d));
                                num8  = IdnMapping.adapt(delta, num3 - num5 + 1, num3 == num4);
                                delta = 0;
                                ++num3;
                                if (IdnMapping.IsSupplementary(cTest))
                                {
                                    ++num3;
                                    ++num5;
                                }
                            }
                            index3 += IdnMapping.IsSupplementary(utf32) ? 2 : 1;
                        }
                        num7 = delta + 1;
                        num6 = num9 + 1;
                    }
                }
                if (stringBuilder.Length - startIndex > 63)
                {
                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "unicode");
                }
                if (num1 != unicode.Length)
                {
                    stringBuilder.Append('.');
                }
                num2       = num1 + 1;
                startIndex = stringBuilder.Length;
            }
            int    length = stringBuilder.Length;
            int    num12  = (int)byte.MaxValue;
            string str1   = unicode;
            int    index4 = str1.Length - 1;
            int    num13  = IdnMapping.IsDot(str1[index4]) ? 0 : 1;
            int    num14  = num12 - num13;

            if (length > num14)
            {
                string   key      = "Argument_IdnBadNameSize";
                object[] objArray = new object[1];
                int      index1   = 0;
                int      num3     = (int)byte.MaxValue;
                string   str2     = unicode;
                int      index2   = str2.Length - 1;
                int      num4     = IdnMapping.IsDot(str2[index2]) ? 0 : 1;
                // ISSUE: variable of a boxed type
                __Boxed <int> local = (ValueType)(num3 - num4);
                objArray[index1] = (object)local;
                throw new ArgumentException(Environment.GetResourceString(key, objArray), "unicode");
            }
            return(stringBuilder.ToString());
        }
        private static string punycode_encode(string unicode)
        {
            if (unicode.Length == 0)
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "unicode");
            }
            StringBuilder builder    = new StringBuilder(unicode.Length);
            int           length     = 0;
            int           startIndex = 0;

            for (int i = 0; length < unicode.Length; i = builder.Length)
            {
                length = unicode.IndexOfAny(M_Dots, startIndex);
                if (length < 0)
                {
                    length = unicode.Length;
                }
                if (length == startIndex)
                {
                    if (length != unicode.Length)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "unicode");
                    }
                    break;
                }
                builder.Append("xn--");
                bool         flag         = false;
                BidiCategory bidiCategory = CharUnicodeInfo.GetBidiCategory(unicode, startIndex);
                switch (bidiCategory)
                {
                case BidiCategory.RightToLeft:
                case BidiCategory.RightToLeftArabic:
                {
                    flag = true;
                    int index = length - 1;
                    if (char.IsLowSurrogate(unicode, index))
                    {
                        index--;
                    }
                    bidiCategory = CharUnicodeInfo.GetBidiCategory(unicode, index);
                    if ((bidiCategory != BidiCategory.RightToLeft) && (bidiCategory != BidiCategory.RightToLeftArabic))
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "unicode");
                    }
                    break;
                }
                }
                int num6 = 0;
                for (int j = startIndex; j < length; j++)
                {
                    BidiCategory category2 = CharUnicodeInfo.GetBidiCategory(unicode, j);
                    if (flag && (category2 == BidiCategory.LeftToRight))
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "unicode");
                    }
                    if (!flag && ((category2 == BidiCategory.RightToLeft) || (category2 == BidiCategory.RightToLeftArabic)))
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "unicode");
                    }
                    if (basic(unicode[j]))
                    {
                        builder.Append(encode_basic(unicode[j]));
                        num6++;
                    }
                    else if (char.IsSurrogatePair(unicode, j))
                    {
                        j++;
                    }
                }
                int num7 = num6;
                if (num7 == (length - startIndex))
                {
                    builder.Remove(i, "xn--".Length);
                }
                else
                {
                    if (((unicode.Length - startIndex) >= "xn--".Length) && unicode.Substring(startIndex, "xn--".Length).Equals("xn--", StringComparison.OrdinalIgnoreCase))
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "unicode");
                    }
                    int num8 = 0;
                    if (num7 > 0)
                    {
                        builder.Append('-');
                    }
                    int num9  = 0x80;
                    int delta = 0;
                    int num11 = 0x48;
                    while (num6 < (length - startIndex))
                    {
                        int cTest = 0;
                        int num13 = 0x7ffffff;
                        int num12 = startIndex;
                        while (num12 < length)
                        {
                            cTest = char.ConvertToUtf32(unicode, num12);
                            if ((cTest >= num9) && (cTest < num13))
                            {
                                num13 = cTest;
                            }
                            num12 += IsSupplementary(cTest) ? 2 : 1;
                        }
                        delta += (num13 - num9) * ((num6 - num8) + 1);
                        num9   = num13;
                        for (num12 = startIndex; num12 < length; num12 += IsSupplementary(cTest) ? 2 : 1)
                        {
                            cTest = char.ConvertToUtf32(unicode, num12);
                            if (cTest < num9)
                            {
                                delta++;
                            }
                            if (cTest == num9)
                            {
                                int d     = delta;
                                int num16 = 0x24;
                                while (true)
                                {
                                    int num17 = (num16 <= num11) ? 1 : ((num16 >= (num11 + 0x1a)) ? 0x1a : (num16 - num11));
                                    if (d < num17)
                                    {
                                        break;
                                    }
                                    builder.Append(encode_digit(num17 + ((d - num17) % (0x24 - num17))));
                                    d      = (d - num17) / (0x24 - num17);
                                    num16 += 0x24;
                                }
                                builder.Append(encode_digit(d));
                                num11 = adapt(delta, (num6 - num8) + 1, num6 == num7);
                                delta = 0;
                                num6++;
                                if (IsSupplementary(num13))
                                {
                                    num6++;
                                    num8++;
                                }
                            }
                        }
                        delta++;
                        num9++;
                    }
                }
                if ((builder.Length - i) > 0x3f)
                {
                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "unicode");
                }
                if (length != unicode.Length)
                {
                    builder.Append('.');
                }
                startIndex = length + 1;
            }
            if (builder.Length > (0xff - (IsDot(unicode[unicode.Length - 1]) ? 0 : 1)))
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadNameSize", new object[] { 0xff - (IsDot(unicode[unicode.Length - 1]) ? 0 : 1) }), "unicode");
            }
            return(builder.ToString());
        }
        private static string punycode_decode(string ascii)
        {
            if (ascii.Length == 0)
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
            }
            if (ascii.Length > (0xff - (IsDot(ascii[ascii.Length - 1]) ? 0 : 1)))
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadNameSize", new object[] { 0xff - (IsDot(ascii[ascii.Length - 1]) ? 0 : 1) }), "ascii");
            }
            StringBuilder builder    = new StringBuilder(ascii.Length);
            int           index      = 0;
            int           startIndex = 0;

            for (int i = 0; index < ascii.Length; i = builder.Length)
            {
                index = ascii.IndexOf('.', startIndex);
                if ((index < 0) || (index > ascii.Length))
                {
                    index = ascii.Length;
                }
                if (index == startIndex)
                {
                    if (index != ascii.Length)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
                    }
                    break;
                }
                if ((index - startIndex) > 0x3f)
                {
                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
                }
                if ((ascii.Length < ("xn--".Length + startIndex)) || !ascii.Substring(startIndex, "xn--".Length).Equals("xn--", StringComparison.OrdinalIgnoreCase))
                {
                    builder.Append(ascii.Substring(startIndex, index - startIndex));
                }
                else
                {
                    int num5;
                    startIndex += "xn--".Length;
                    int num4 = ascii.LastIndexOf('-', index - 1);
                    if (num4 == (index - 1))
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                    }
                    if (num4 <= startIndex)
                    {
                        num5 = 0;
                    }
                    else
                    {
                        num5 = num4 - startIndex;
                        for (int k = startIndex; k < (startIndex + num5); k++)
                        {
                            if (ascii[k] > '\x007f')
                            {
                                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                            }
                            builder.Append(((ascii[k] >= 'A') && (ascii[k] <= 'Z')) ? ((char)((ascii[k] - 'A') + 0x61)) : ascii[k]);
                        }
                    }
                    int num7  = startIndex + ((num5 > 0) ? (num5 + 1) : 0);
                    int num8  = 0x80;
                    int num9  = 0x48;
                    int num10 = 0;
                    int num13 = 0;
                    while (num7 < index)
                    {
                        int num17;
                        int num14 = num10;
                        int num11 = 1;
                        int num12 = 0x24;
                        while (true)
                        {
                            if (num7 >= index)
                            {
                                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                            }
                            int num15 = decode_digit(ascii[num7++]);
                            if (num15 > ((0x7ffffff - num10) / num11))
                            {
                                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                            }
                            num10 += num15 * num11;
                            int num16 = (num12 <= num9) ? 1 : ((num12 >= (num9 + 0x1a)) ? 0x1a : (num12 - num9));
                            if (num15 < num16)
                            {
                                break;
                            }
                            if (num11 > (0x7ffffff / (0x24 - num16)))
                            {
                                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                            }
                            num11 *= 0x24 - num16;
                            num12 += 0x24;
                        }
                        num9 = adapt(num10 - num14, ((builder.Length - i) - num13) + 1, num14 == 0);
                        if ((num10 / (((builder.Length - i) - num13) + 1)) > (0x7ffffff - num8))
                        {
                            throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                        }
                        num8 += num10 / (((builder.Length - i) - num13) + 1);
                        num10 = num10 % (((builder.Length - i) - num13) + 1);
                        if (((num8 < 0) || (num8 > 0x10ffff)) || ((num8 >= 0xd800) && (num8 <= 0xdfff)))
                        {
                            throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                        }
                        string str = char.ConvertFromUtf32(num8);
                        if (num13 > 0)
                        {
                            int num18 = num10;
                            num17 = i;
                            while (num18 > 0)
                            {
                                if (num17 >= builder.Length)
                                {
                                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                }
                                if (char.IsSurrogate(builder[num17]))
                                {
                                    num17++;
                                }
                                num18--;
                                num17++;
                            }
                        }
                        else
                        {
                            num17 = i + num10;
                        }
                        builder.Insert(num17, str);
                        if (IsSupplementary(num8))
                        {
                            num13++;
                        }
                        num10++;
                    }
                    bool         flag         = false;
                    BidiCategory bidiCategory = CharUnicodeInfo.GetBidiCategory(builder.ToString(), i);
                    switch (bidiCategory)
                    {
                    case BidiCategory.RightToLeft:
                    case BidiCategory.RightToLeftArabic:
                        flag = true;
                        break;
                    }
                    for (int j = i; j < builder.Length; j++)
                    {
                        if (!char.IsLowSurrogate(builder.ToString(), j))
                        {
                            bidiCategory = CharUnicodeInfo.GetBidiCategory(builder.ToString(), j);
                            if ((flag && (bidiCategory == BidiCategory.LeftToRight)) || (!flag && ((bidiCategory == BidiCategory.RightToLeft) || (bidiCategory == BidiCategory.RightToLeftArabic))))
                            {
                                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "ascii");
                            }
                        }
                    }
                    if ((flag && (bidiCategory != BidiCategory.RightToLeft)) && (bidiCategory != BidiCategory.RightToLeftArabic))
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "ascii");
                    }
                }
                if ((index - startIndex) > 0x3f)
                {
                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
                }
                if (index != ascii.Length)
                {
                    builder.Append('.');
                }
                startIndex = index + 1;
            }
            if (builder.Length > (0xff - (IsDot(builder[builder.Length - 1]) ? 0 : 1)))
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadNameSize", new object[] { 0xff - (IsDot(builder[builder.Length - 1]) ? 0 : 1) }), "ascii");
            }
            return(builder.ToString());
        }
Пример #7
0
        // Token: 0x06002FE3 RID: 12259 RVA: 0x000B7D34 File Offset: 0x000B5F34
        private static string punycode_decode(string ascii)
        {
            if (ascii.Length == 0)
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
            }
            if (ascii.Length > 255 - (IdnMapping.IsDot(ascii[ascii.Length - 1]) ? 0 : 1))
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadNameSize", new object[]
                {
                    255 - (IdnMapping.IsDot(ascii[ascii.Length - 1]) ? 0 : 1)
                }), "ascii");
            }
            StringBuilder stringBuilder = new StringBuilder(ascii.Length);
            int           i             = 0;
            int           num           = 0;
            int           num2          = 0;

            while (i < ascii.Length)
            {
                i = ascii.IndexOf('.', num);
                if (i < 0 || i > ascii.Length)
                {
                    i = ascii.Length;
                }
                if (i == num)
                {
                    if (i != ascii.Length)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
                    }
                    break;
                }
                else
                {
                    if (i - num > 63)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
                    }
                    if (ascii.Length < "xn--".Length + num || !ascii.Substring(num, "xn--".Length).Equals("xn--", StringComparison.OrdinalIgnoreCase))
                    {
                        stringBuilder.Append(ascii.Substring(num, i - num));
                    }
                    else
                    {
                        num += "xn--".Length;
                        int num3 = ascii.LastIndexOf('-', i - 1);
                        if (num3 == i - 1)
                        {
                            throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                        }
                        int num4;
                        if (num3 <= num)
                        {
                            num4 = 0;
                        }
                        else
                        {
                            num4 = num3 - num;
                            for (int j = num; j < num + num4; j++)
                            {
                                if (ascii[j] > '\u007f')
                                {
                                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                }
                                stringBuilder.Append((ascii[j] >= 'A' && ascii[j] <= 'Z') ? (ascii[j] - 'A' + 'a') : ascii[j]);
                            }
                        }
                        int k    = num + ((num4 > 0) ? (num4 + 1) : 0);
                        int num5 = 128;
                        int num6 = 72;
                        int num7 = 0;
                        int num8 = 0;
IL_40D:
                        while (k < i)
                        {
                            int num9  = num7;
                            int num10 = 1;
                            int num11 = 36;
                            while (k < i)
                            {
                                int num12 = IdnMapping.decode_digit(ascii[k++]);
                                if (num12 > (134217727 - num7) / num10)
                                {
                                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                }
                                num7 += num12 * num10;
                                int num13 = (num11 <= num6) ? 1 : ((num11 >= num6 + 26) ? 26 : (num11 - num6));
                                if (num12 >= num13)
                                {
                                    if (num10 > 134217727 / (36 - num13))
                                    {
                                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                    }
                                    num10 *= 36 - num13;
                                    num11 += 36;
                                }
                                else
                                {
                                    num6 = IdnMapping.adapt(num7 - num9, stringBuilder.Length - num2 - num8 + 1, num9 == 0);
                                    if (num7 / (stringBuilder.Length - num2 - num8 + 1) > 134217727 - num5)
                                    {
                                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                    }
                                    num5 += num7 / (stringBuilder.Length - num2 - num8 + 1);
                                    num7 %= stringBuilder.Length - num2 - num8 + 1;
                                    if (num5 < 0 || num5 > 1114111 || (num5 >= 55296 && num5 <= 57343))
                                    {
                                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                    }
                                    string value = char.ConvertFromUtf32(num5);
                                    int    num14;
                                    if (num8 > 0)
                                    {
                                        int l = num7;
                                        num14 = num2;
                                        while (l > 0)
                                        {
                                            if (num14 >= stringBuilder.Length)
                                            {
                                                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                                            }
                                            if (char.IsSurrogate(stringBuilder[num14]))
                                            {
                                                num14++;
                                            }
                                            l--;
                                            num14++;
                                        }
                                    }
                                    else
                                    {
                                        num14 = num2 + num7;
                                    }
                                    stringBuilder.Insert(num14, value);
                                    if (IdnMapping.IsSupplementary(num5))
                                    {
                                        num8++;
                                    }
                                    num7++;
                                    goto IL_40D;
                                }
                            }
                            throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "ascii");
                        }
                        bool         flag         = false;
                        BidiCategory bidiCategory = CharUnicodeInfo.GetBidiCategory(stringBuilder.ToString(), num2);
                        if (bidiCategory == BidiCategory.RightToLeft || bidiCategory == BidiCategory.RightToLeftArabic)
                        {
                            flag = true;
                        }
                        for (int m = num2; m < stringBuilder.Length; m++)
                        {
                            if (!char.IsLowSurrogate(stringBuilder.ToString(), m))
                            {
                                bidiCategory = CharUnicodeInfo.GetBidiCategory(stringBuilder.ToString(), m);
                                if ((flag && bidiCategory == BidiCategory.LeftToRight) || (!flag && (bidiCategory == BidiCategory.RightToLeft || bidiCategory == BidiCategory.RightToLeftArabic)))
                                {
                                    throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "ascii");
                                }
                            }
                        }
                        if (flag && bidiCategory != BidiCategory.RightToLeft && bidiCategory != BidiCategory.RightToLeftArabic)
                        {
                            throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "ascii");
                        }
                    }
                    if (i - num > 63)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "ascii");
                    }
                    if (i != ascii.Length)
                    {
                        stringBuilder.Append('.');
                    }
                    num  = i + 1;
                    num2 = stringBuilder.Length;
                }
            }
            if (stringBuilder.Length > 255 - (IdnMapping.IsDot(stringBuilder[stringBuilder.Length - 1]) ? 0 : 1))
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadNameSize", new object[]
                {
                    255 - (IdnMapping.IsDot(stringBuilder[stringBuilder.Length - 1]) ? 0 : 1)
                }), "ascii");
            }
            return(stringBuilder.ToString());
        }
Пример #8
0
        // Token: 0x06002FE2 RID: 12258 RVA: 0x000B7924 File Offset: 0x000B5B24
        private static string punycode_encode(string unicode)
        {
            if (unicode.Length == 0)
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "unicode");
            }
            StringBuilder stringBuilder = new StringBuilder(unicode.Length);
            int           i             = 0;
            int           num           = 0;
            int           num2          = 0;

            while (i < unicode.Length)
            {
                i = unicode.IndexOfAny(IdnMapping.M_Dots, num);
                if (i < 0)
                {
                    i = unicode.Length;
                }
                if (i == num)
                {
                    if (i != unicode.Length)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "unicode");
                    }
                    break;
                }
                else
                {
                    stringBuilder.Append("xn--");
                    bool         flag         = false;
                    BidiCategory bidiCategory = CharUnicodeInfo.GetBidiCategory(unicode, num);
                    if (bidiCategory == BidiCategory.RightToLeft || bidiCategory == BidiCategory.RightToLeftArabic)
                    {
                        flag = true;
                        int num3 = i - 1;
                        if (char.IsLowSurrogate(unicode, num3))
                        {
                            num3--;
                        }
                        bidiCategory = CharUnicodeInfo.GetBidiCategory(unicode, num3);
                        if (bidiCategory != BidiCategory.RightToLeft && bidiCategory != BidiCategory.RightToLeftArabic)
                        {
                            throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "unicode");
                        }
                    }
                    int j = 0;
                    for (int k = num; k < i; k++)
                    {
                        BidiCategory bidiCategory2 = CharUnicodeInfo.GetBidiCategory(unicode, k);
                        if (flag && bidiCategory2 == BidiCategory.LeftToRight)
                        {
                            throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "unicode");
                        }
                        if (!flag && (bidiCategory2 == BidiCategory.RightToLeft || bidiCategory2 == BidiCategory.RightToLeftArabic))
                        {
                            throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadBidi"), "unicode");
                        }
                        if (IdnMapping.basic((uint)unicode[k]))
                        {
                            stringBuilder.Append(IdnMapping.encode_basic(unicode[k]));
                            j++;
                        }
                        else if (char.IsSurrogatePair(unicode, k))
                        {
                            k++;
                        }
                    }
                    int num4 = j;
                    if (num4 == i - num)
                    {
                        stringBuilder.Remove(num2, "xn--".Length);
                    }
                    else
                    {
                        if (unicode.Length - num >= "xn--".Length && unicode.Substring(num, "xn--".Length).Equals("xn--", StringComparison.OrdinalIgnoreCase))
                        {
                            throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadPunycode"), "unicode");
                        }
                        int num5 = 0;
                        if (num4 > 0)
                        {
                            stringBuilder.Append('-');
                        }
                        int num6 = 128;
                        int num7 = 0;
                        int num8 = 72;
                        while (j < i - num)
                        {
                            int num9 = 134217727;
                            int num10;
                            for (int l = num; l < i; l += (IdnMapping.IsSupplementary(num10) ? 2 : 1))
                            {
                                num10 = char.ConvertToUtf32(unicode, l);
                                if (num10 >= num6 && num10 < num9)
                                {
                                    num9 = num10;
                                }
                            }
                            num7 += (num9 - num6) * (j - num5 + 1);
                            num6  = num9;
                            for (int l = num; l < i; l += (IdnMapping.IsSupplementary(num10) ? 2 : 1))
                            {
                                num10 = char.ConvertToUtf32(unicode, l);
                                if (num10 < num6)
                                {
                                    num7++;
                                }
                                if (num10 == num6)
                                {
                                    int num11 = num7;
                                    int num12 = 36;
                                    for (;;)
                                    {
                                        int num13 = (num12 <= num8) ? 1 : ((num12 >= num8 + 26) ? 26 : (num12 - num8));
                                        if (num11 < num13)
                                        {
                                            break;
                                        }
                                        stringBuilder.Append(IdnMapping.encode_digit(num13 + (num11 - num13) % (36 - num13)));
                                        num11  = (num11 - num13) / (36 - num13);
                                        num12 += 36;
                                    }
                                    stringBuilder.Append(IdnMapping.encode_digit(num11));
                                    num8 = IdnMapping.adapt(num7, j - num5 + 1, j == num4);
                                    num7 = 0;
                                    j++;
                                    if (IdnMapping.IsSupplementary(num9))
                                    {
                                        j++;
                                        num5++;
                                    }
                                }
                            }
                            num7++;
                            num6++;
                        }
                    }
                    if (stringBuilder.Length - num2 > 63)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadLabelSize"), "unicode");
                    }
                    if (i != unicode.Length)
                    {
                        stringBuilder.Append('.');
                    }
                    num  = i + 1;
                    num2 = stringBuilder.Length;
                }
            }
            if (stringBuilder.Length > 255 - (IdnMapping.IsDot(unicode[unicode.Length - 1]) ? 0 : 1))
            {
                throw new ArgumentException(Environment.GetResourceString("Argument_IdnBadNameSize", new object[]
                {
                    255 - (IdnMapping.IsDot(unicode[unicode.Length - 1]) ? 0 : 1)
                }), "unicode");
            }
            return(stringBuilder.ToString());
        }