Example #1
0
        public static string UnescapeDataString(string stringToUnescape)
        {
            if ((object)stringToUnescape == null)
            {
                throw new ArgumentNullException(nameof(stringToUnescape));
            }

            if (stringToUnescape.Length == 0)
            {
                return(string.Empty);
            }

            unsafe
            {
                fixed(char *pStr = stringToUnescape)
                {
                    int position;

                    for (position = 0; position < stringToUnescape.Length; ++position)
                    {
                        if (pStr[position] == '%')
                        {
                            break;
                        }
                    }

                    if (position == stringToUnescape.Length)
                    {
                        return(stringToUnescape);
                    }

                    UnescapeMode unescapeMode = UnescapeMode.Unescape | UnescapeMode.UnescapeAll;

                    position = 0;
                    ValueStringBuilder vsb = new ValueStringBuilder(stringToUnescape.Length);

                    UriHelper.UnescapeString(stringToUnescape, 0, stringToUnescape.Length, ref vsb, ref position,
                                             c_DummyChar, c_DummyChar, c_DummyChar, unescapeMode, null, false);

                    ReadOnlySpan <char> resultSpan = vsb.AsSpan(0, position);
                    string result = resultSpan.SequenceEqual(stringToUnescape) ? stringToUnescape : resultSpan.ToString();

                    vsb.Dispose();
                    return(result);
                }
            }
        }
Example #2
0
        public static string UnescapeDataString(string stringToUnescape)
        {
            if ((object)stringToUnescape == null)
            {
                throw new ArgumentNullException("stringToUnescape");
            }

            if (stringToUnescape.Length == 0)
            {
                return(string.Empty);
            }

            unsafe
            {
                fixed(char *pStr = stringToUnescape)
                {
                    int position;

                    for (position = 0; position < stringToUnescape.Length; ++position)
                    {
                        if (pStr[position] == '%')
                        {
                            break;
                        }
                    }

                    if (position == stringToUnescape.Length)
                    {
                        return(stringToUnescape);
                    }

                    UnescapeMode unescapeMode = UnescapeMode.Unescape | UnescapeMode.UnescapeAll;

                    position = 0;
                    char[] dest = new char[stringToUnescape.Length];
                    dest = UriHelper.UnescapeString(stringToUnescape, 0, stringToUnescape.Length, dest, ref position,
                                                    c_DummyChar, c_DummyChar, c_DummyChar, unescapeMode, null, false);
                    return(new string(dest, 0, position));
                }
            }
        }
        internal unsafe static char[] UnescapeString(char* pStr, int start, int end, char[] dest, ref int destPosition, 
            char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, bool isQuery)
        {
            byte [] bytes = null;
            byte escapedReallocations = 0;
            bool escapeReserved = false;
            int next = start;
            bool iriParsing = Uri.IriParsingStatic(syntax)
                                && ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.EscapeUnescape);
            
            while (true)
            {
                // we may need to re-pin dest[]
                fixed (char* pDest = dest)
                {
                    if ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.CopyOnly)
                    {
                        while (start < end)
                            pDest[destPosition++] = pStr[start++];
                        return dest;
                    }

                    while (true)
                    {
                        char ch = (char)0;

                        for (;next < end; ++next)
                        {
                            if ((ch = pStr[next]) == '%')
                            {
                                if ((unescapeMode & UnescapeMode.Unescape) == 0)
                                {
                                    // re-escape, don't check anything else
                                    escapeReserved = true;
                                }
                                else if (next+2 < end)
                                {
                                    ch = EscapedAscii(pStr[next+1], pStr[next+2]);
                                    // Unescape a good sequence if full unescape is requested
                                    if (unescapeMode >= UnescapeMode.UnescapeAll)
                                    {
                                        if (ch == Uri.c_DummyChar)
                                        {
                                            if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
                                            {
                                                // Should be a rare case where the app tries to feed an invalid escaped sequence
                                                throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
                                            }
                                            continue;
                                        }
                                    }
                                    // re-escape % from an invalid sequence
                                    else if (ch == Uri.c_DummyChar)
                                    {
                                        if ((unescapeMode & UnescapeMode.Escape) != 0)
                                            escapeReserved = true;
                                        else
                                            continue;   // we should throw instead but since v1.0 woudl just print '%'
                                    }
                                    // Do not unescape '%' itself unless full unescape is requested
                                    else if (ch == '%')
                                    {
                                        next += 2;
                                        continue;
                                    }
                                    // Do not unescape a reserved char unless full unescape is requested
                                    else if (ch == rsvd1 || ch == rsvd2 || ch == rsvd3)
                                    {
                                        next += 2;
                                        continue;
                                    }
                                    // Do not unescape a dangerous char unless it's V1ToStringFlags mode
                                    else if ((unescapeMode & UnescapeMode.V1ToStringFlag) == 0 && IsNotSafeForUnescape(ch))
                                    {
                                        next += 2;
                                        continue;
                                    }
                                    else if (iriParsing && ((ch <='\x9F' && IsNotSafeForUnescape(ch)) || 
                                                            (ch >'\x9F' &&!Uri.CheckIriUnicodeRange(ch, isQuery))))
                                    {
                                        // check if unenscaping gives a char ouside iri range 
                                        // if it does then keep it escaped
                                        next += 2;
                                        continue;
                                    }
                                    // unescape escaped char or escape %
                                    break;
                                }
                                else if (unescapeMode >= UnescapeMode.UnescapeAll)
                                {
                                    if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
                                    {
                                        // Should be a rare case where the app tries to feed an invalid escaped sequence
                                        throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
                                    }
                                    // keep a '%' as part of a bogus sequence 
                                    continue;
                                }
                                else
                                {
                                    escapeReserved = true;
                                }
                                // escape (escapeReserved==ture) or otheriwse unescape the sequence
                                break;
                            }
                            else if ((unescapeMode & (UnescapeMode.Unescape | UnescapeMode.UnescapeAll)) 
                                == (UnescapeMode.Unescape | UnescapeMode.UnescapeAll))
                            {
                                continue;
                            }
                            else if ((unescapeMode & UnescapeMode.Escape) != 0)
                            {
                                 // Could actually escape some of the characters
                                 if (ch == rsvd1 || ch == rsvd2 || ch == rsvd3)
                                 {
                                     // found an unescaped reserved character -> escape it
                                     escapeReserved = true;
                                     break;
                                 }
                                 else if ((unescapeMode & UnescapeMode.V1ToStringFlag) == 0 
                                     && (ch <= '\x1F' || (ch >= '\x7F' && ch <= '\x9F')))
                                 {
                                     // found an unescaped reserved character -> escape it
                                     escapeReserved = true;
                                     break;
                                 }
                            }
                        }

                        //copy off previous characters from input
                        while (start < next)
                            pDest[destPosition++] = pStr[start++];

                        if (next != end)
                        {
                            //VsWhidbey#87423
                            if (escapeReserved)
                            {
                                //escape that char
                                // Since this should be _really_ rare case, reallocate with constant size increase of 30 rsvd-type characters.
                                if (escapedReallocations == 0)
                                {
                                    escapedReallocations = 30;
                                    char[] newDest = new char[dest.Length + escapedReallocations*3];
                                    fixed (char *pNewDest = newDest)
                                    {
                                        for (int i = 0; i < destPosition; ++i)
                                            pNewDest[i] = pDest[i];
                                    }
                                    dest = newDest;
                                    // re-pin new dest[] array
                                    goto dest_fixed_loop_break;
                                }
                                else
                                {
                                    --escapedReallocations;
                                    EscapeAsciiChar(pStr[next], dest, ref destPosition);
                                    escapeReserved = false;
                                    start = ++next;
                                    continue;
                                }
                            }

                            // unescaping either one Ascii or possibly multiple Unicode

                            if (ch <= '\x7F')
                            {
                                //ASCII
                                dest[destPosition++] = ch;
                                next+=3;
                                start = next;
                                continue;
                            }

                            // Unicode

                            int byteCount = 1;
                            // lazy initialization of max size, will reuse the array for next sequences
                            if ((object) bytes == null)
                                bytes = new byte[end - next];

                            bytes[0] = (byte)ch;
                            next+=3;
                            while (next < end)
                            {
                                // Check on exit criterion
                                if ((ch = pStr[next]) != '%' || next+2 >= end)
                                    break;

                                // already made sure we have 3 characters in str
                                ch = EscapedAscii(pStr[next+1], pStr[next+2]);

                                //invalid hex sequence ?
                                if (ch == Uri.c_DummyChar)
                                    break;
                                // character is not part of a UTF-8 sequence ?
                                else if (ch < '\x80')
                                    break;
                                else
                                {
                                    //a UTF-8 sequence
                                    bytes[byteCount++] = (byte)ch;
                                    next += 3;
                                }
                            }
                            Encoding noFallbackCharUTF8 = (Encoding)Encoding.UTF8.Clone();
                            noFallbackCharUTF8.EncoderFallback = new EncoderReplacementFallback("");
                            noFallbackCharUTF8.DecoderFallback = new DecoderReplacementFallback("");

                            char[] unescapedChars = new char[bytes.Length];
                            int charCount = noFallbackCharUTF8.GetChars(bytes, 0, byteCount, unescapedChars, 0);

                            start = next;

                            // match exact bytes
                            // Do not unescape chars not allowed by Iri
                            // need to check for invalid utf sequences that may not have given any chars

                            MatchUTF8Sequence(pDest, dest, ref destPosition, unescapedChars, charCount, bytes, 
                                byteCount, isQuery, iriParsing);
                        }

                        if (next == end)
                            goto done;
                    }
dest_fixed_loop_break: ;
                }
            }

done:       return dest;
        }
 //
 // This method will assume that any good Escaped Sequence will be unescaped in the output
 // - Assumes Dest.Length - detPosition >= end-start
 // - UnescapeLevel controls various modes of opearion
 // - Any "bad" escape sequence will remain as is or '%' will be escaped.
 // - destPosition tells the starting index in dest for placing the result.
 //   On return destPosition tells the last character + 1 postion in the "dest" array.
 // - The control chars and chars passed in rsdvX parameters may be re-escaped depending on UnescapeLevel
 // - It is a RARE case when Unescape actually needs escaping some characteres mentioned above.
 //   For this reason it returns a char[] that is usually the same ref as the input "dest" value.
 //
 internal unsafe static char[] UnescapeString(string input, int start, int end, char[] dest, 
     ref int destPosition, char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, 
     bool isQuery)
 {
     fixed (char *pStr = input)
     {
         return UnescapeString(pStr, start, end, dest, ref destPosition, rsvd1, rsvd2, rsvd3, unescapeMode, 
             syntax, isQuery);
     }
 }
Example #5
0
        internal unsafe static char[] UnescapeString(char *pStr, int start, int end, char[] dest, ref int destPosition,
                                                     char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, bool isQuery)
        {
            byte [] bytes = null;
            byte    escapedReallocations = 0;
            bool    escapeReserved       = false;
            int     next       = start;
            bool    iriParsing = Uri.IriParsingStatic(syntax) &&
                                 ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.EscapeUnescape);

            while (true)
            {
                // we may need to re-pin dest[]
                fixed(char *pDest = dest)
                {
                    if ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.CopyOnly)
                    {
                        while (start < end)
                        {
                            pDest[destPosition++] = pStr[start++];
                        }
                        return(dest);
                    }

                    while (true)
                    {
                        char ch = (char)0;

                        for (; next < end; ++next)
                        {
                            if ((ch = pStr[next]) == '%')
                            {
                                if ((unescapeMode & UnescapeMode.Unescape) == 0)
                                {
                                    // re-escape, don't check anything else
                                    escapeReserved = true;
                                }
                                else if (next + 2 < end)
                                {
                                    ch = EscapedAscii(pStr[next + 1], pStr[next + 2]);
                                    // Unescape a good sequence if full unescape is requested
                                    if (unescapeMode >= UnescapeMode.UnescapeAll)
                                    {
                                        if (ch == Uri.c_DummyChar)
                                        {
                                            if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
                                            {
                                                // Should be a rare case where the app tries to feed an invalid escaped sequence
                                                throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
                                            }
                                            continue;
                                        }
                                    }
                                    // re-escape % from an invalid sequence
                                    else if (ch == Uri.c_DummyChar)
                                    {
                                        if ((unescapeMode & UnescapeMode.Escape) != 0)
                                        {
                                            escapeReserved = true;
                                        }
                                        else
                                        {
                                            continue;   // we should throw instead but since v1.0 woudl just print '%'
                                        }
                                    }
                                    // Do not unescape '%' itself unless full unescape is requested
                                    else if (ch == '%')
                                    {
                                        next += 2;
                                        continue;
                                    }
                                    // Do not unescape a reserved char unless full unescape is requested
                                    else if (ch == rsvd1 || ch == rsvd2 || ch == rsvd3)
                                    {
                                        next += 2;
                                        continue;
                                    }
                                    // Do not unescape a dangerous char unless it's V1ToStringFlags mode
                                    else if ((unescapeMode & UnescapeMode.V1ToStringFlag) == 0 && IsNotSafeForUnescape(ch))
                                    {
                                        next += 2;
                                        continue;
                                    }
                                    else if (iriParsing && ((ch <= '\x9F' && IsNotSafeForUnescape(ch)) ||
                                                            (ch > '\x9F' && !IriHelper.CheckIriUnicodeRange(ch, isQuery))))
                                    {
                                        // check if unenscaping gives a char ouside iri range
                                        // if it does then keep it escaped
                                        next += 2;
                                        continue;
                                    }
                                    // unescape escaped char or escape %
                                    break;
                                }
                                else if (unescapeMode >= UnescapeMode.UnescapeAll)
                                {
                                    if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
                                    {
                                        // Should be a rare case where the app tries to feed an invalid escaped sequence
                                        throw new UriFormatException(SR.GetString(SR.net_uri_BadString));
                                    }
                                    // keep a '%' as part of a bogus sequence
                                    continue;
                                }
                                else
                                {
                                    escapeReserved = true;
                                }
                                // escape (escapeReserved==ture) or otheriwse unescape the sequence
                                break;
                            }
                            else if ((unescapeMode & (UnescapeMode.Unescape | UnescapeMode.UnescapeAll))
                                     == (UnescapeMode.Unescape | UnescapeMode.UnescapeAll))
                            {
                                continue;
                            }
                            else if ((unescapeMode & UnescapeMode.Escape) != 0)
                            {
                                // Could actually escape some of the characters
                                if (ch == rsvd1 || ch == rsvd2 || ch == rsvd3)
                                {
                                    // found an unescaped reserved character -> escape it
                                    escapeReserved = true;
                                    break;
                                }
                                else if ((unescapeMode & UnescapeMode.V1ToStringFlag) == 0 &&
                                         (ch <= '\x1F' || (ch >= '\x7F' && ch <= '\x9F')))
                                {
                                    // found an unescaped reserved character -> escape it
                                    escapeReserved = true;
                                    break;
                                }
                            }
                        }

                        //copy off previous characters from input
                        while (start < next)
                        {
                            pDest[destPosition++] = pStr[start++];
                        }

                        if (next != end)
                        {
                            //VsWhidbey#87423
                            if (escapeReserved)
                            {
                                //escape that char
                                // Since this should be _really_ rare case, reallocate with constant size increase of 30 rsvd-type characters.
                                if (escapedReallocations == 0)
                                {
                                    escapedReallocations = 30;
                                    char[] newDest = new char[dest.Length + escapedReallocations * 3];
                                    fixed(char *pNewDest = newDest)
                                    {
                                        for (int i = 0; i < destPosition; ++i)
                                        {
                                            pNewDest[i] = pDest[i];
                                        }
                                    }

                                    dest = newDest;
                                    // re-pin new dest[] array
                                    goto dest_fixed_loop_break;
                                }
                                else
                                {
                                    --escapedReallocations;
                                    EscapeAsciiChar(pStr[next], dest, ref destPosition);
                                    escapeReserved = false;
                                    start          = ++next;
                                    continue;
                                }
                            }

                            // unescaping either one Ascii or possibly multiple Unicode

                            if (ch <= '\x7F')
                            {
                                //ASCII
                                dest[destPosition++] = ch;
                                next += 3;
                                start = next;
                                continue;
                            }

                            // Unicode

                            int byteCount = 1;
                            // lazy initialization of max size, will reuse the array for next sequences
                            if ((object)bytes == null)
                            {
                                bytes = new byte[end - next];
                            }

                            bytes[0] = (byte)ch;
                            next    += 3;
                            while (next < end)
                            {
                                // Check on exit criterion
                                if ((ch = pStr[next]) != '%' || next + 2 >= end)
                                {
                                    break;
                                }

                                // already made sure we have 3 characters in str
                                ch = EscapedAscii(pStr[next + 1], pStr[next + 2]);

                                //invalid hex sequence ?
                                if (ch == Uri.c_DummyChar)
                                {
                                    break;
                                }
                                // character is not part of a UTF-8 sequence ?
                                else if (ch < '\x80')
                                {
                                    break;
                                }
                                else
                                {
                                    //a UTF-8 sequence
                                    bytes[byteCount++] = (byte)ch;
                                    next += 3;
                                }
                            }
                            Encoding noFallbackCharUTF8 = (Encoding)Encoding.UTF8.Clone();
                            noFallbackCharUTF8.EncoderFallback = new EncoderReplacementFallback("");
                            noFallbackCharUTF8.DecoderFallback = new DecoderReplacementFallback("");

                            char[] unescapedChars = new char[bytes.Length];
                            int    charCount      = noFallbackCharUTF8.GetChars(bytes, 0, byteCount, unescapedChars, 0);

                            start = next;

                            // match exact bytes
                            // Do not unescape chars not allowed by Iri
                            // need to check for invalid utf sequences that may not have given any chars

                            MatchUTF8Sequence(pDest, dest, ref destPosition, unescapedChars, charCount, bytes,
                                              byteCount, isQuery, iriParsing);
                        }

                        if (next == end)
                        {
                            goto done;
                        }
                    }
                    dest_fixed_loop_break :;
                }
            }

            done :       return(dest);
        }
Example #6
0
 //
 // This method will assume that any good Escaped Sequence will be unescaped in the output
 // - Assumes Dest.Length - detPosition >= end-start
 // - UnescapeLevel controls various modes of opearion
 // - Any "bad" escape sequence will remain as is or '%' will be escaped.
 // - destPosition tells the starting index in dest for placing the result.
 //   On return destPosition tells the last character + 1 postion in the "dest" array.
 // - The control chars and chars passed in rsdvX parameters may be re-escaped depending on UnescapeLevel
 // - It is a RARE case when Unescape actually needs escaping some characteres mentioned above.
 //   For this reason it returns a char[] that is usually the same ref as the input "dest" value.
 //
 internal unsafe static char[] UnescapeString(string input, int start, int end, char[] dest,
                                              ref int destPosition, char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax,
                                              bool isQuery)
 {
     fixed(char *pStr = input)
     {
         return(UnescapeString(pStr, start, end, dest, ref destPosition, rsvd1, rsvd2, rsvd3, unescapeMode,
                               syntax, isQuery));
     }
 }
 private static unsafe char[] UnescapeString(char* pStr, int start, int end, char[] dest, ref int destPosition, char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, bool isQuery, bool readOnlyConfig)
 {
     byte[] bytes = null;
     byte num = 0;
     bool flag = false;
     int index = start;
     bool iriParsing = (s_IriParsing && (readOnlyConfig || (!readOnlyConfig && IriParsingStatic(syntax)))) && ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.EscapeUnescape);
 Label_002E:;
     try
     {
         fixed (char* chRef = dest)
         {
             char ch;
             if ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.CopyOnly)
             {
                 while (start < end)
                 {
                     chRef[destPosition++] = pStr[start++];
                 }
                 return dest;
             }
         Label_007F:
             ch = '\0';
             while (index < end)
             {
                 ch = pStr[index];
                 if (ch == '%')
                 {
                     if ((unescapeMode & UnescapeMode.Unescape) == UnescapeMode.CopyOnly)
                     {
                         flag = true;
                     }
                     else
                     {
                         if ((index + 2) < end)
                         {
                             ch = EscapedAscii(pStr[index + 1], pStr[index + 2]);
                             if (unescapeMode >= UnescapeMode.UnescapeAll)
                             {
                                 if (ch == 0xffff)
                                 {
                                     if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
                                     {
                                         throw new UriFormatException(System.SR.GetString("net_uri_BadString"));
                                     }
                                     goto Label_01E8;
                                 }
                                 break;
                             }
                             if (ch == 0xffff)
                             {
                                 if ((unescapeMode & UnescapeMode.Escape) == UnescapeMode.CopyOnly)
                                 {
                                     goto Label_01E8;
                                 }
                                 flag = true;
                                 break;
                             }
                             if (ch == '%')
                             {
                                 index += 2;
                             }
                             else if (((ch == rsvd1) || (ch == rsvd2)) || (ch == rsvd3))
                             {
                                 index += 2;
                             }
                             else if (((unescapeMode & UnescapeMode.V1ToStringFlag) == UnescapeMode.CopyOnly) && IsNotSafeForUnescape(ch))
                             {
                                 index += 2;
                             }
                             else
                             {
                                 if (!iriParsing || (((ch > '\x009f') || !IsNotSafeForUnescape(ch)) && ((ch <= '\x009f') || CheckIriUnicodeRange(ch, isQuery))))
                                 {
                                     break;
                                 }
                                 index += 2;
                             }
                             goto Label_01E8;
                         }
                         if (unescapeMode >= UnescapeMode.UnescapeAll)
                         {
                             if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
                             {
                                 throw new UriFormatException(System.SR.GetString("net_uri_BadString"));
                             }
                             goto Label_01E8;
                         }
                         flag = true;
                     }
                     break;
                 }
                 if (((unescapeMode & (UnescapeMode.UnescapeAll | UnescapeMode.Unescape)) != (UnescapeMode.UnescapeAll | UnescapeMode.Unescape)) && ((unescapeMode & UnescapeMode.Escape) != UnescapeMode.CopyOnly))
                 {
                     if (((ch == rsvd1) || (ch == rsvd2)) || (ch == rsvd3))
                     {
                         flag = true;
                         break;
                     }
                     if (((unescapeMode & UnescapeMode.V1ToStringFlag) == UnescapeMode.CopyOnly) && ((ch <= '\x001f') || ((ch >= '\x007f') && (ch <= '\x009f'))))
                     {
                         flag = true;
                         break;
                     }
                 }
             Label_01E8:
                 index++;
             }
             while (start < index)
             {
                 chRef[destPosition++] = pStr[start++];
             }
             if (index != end)
             {
                 if (flag)
                 {
                     if (num == 0)
                     {
                         num = 30;
                         char[] chArray = new char[dest.Length + (num * 3)];
                         fixed (char* chRef2 = chArray)
                         {
                             for (int i = 0; i < destPosition; i++)
                             {
                                 chRef2[i] = chRef[i];
                             }
                         }
                         dest = chArray;
                         goto Label_002E;
                     }
                     num = (byte) (num - 1);
                     EscapeAsciiChar(pStr[index], dest, ref destPosition);
                     flag = false;
                     start = ++index;
                     goto Label_007F;
                 }
                 if (ch <= '\x007f')
                 {
                     dest[destPosition++] = ch;
                     index += 3;
                     start = index;
                     goto Label_007F;
                 }
                 int byteCount = 1;
                 if (bytes == null)
                 {
                     bytes = new byte[end - index];
                 }
                 bytes[0] = (byte) ch;
                 index += 3;
                 while (index < end)
                 {
                     if (((ch = pStr[index]) != '%') || ((index + 2) >= end))
                     {
                         break;
                     }
                     ch = EscapedAscii(pStr[index + 1], pStr[index + 2]);
                     if ((ch == 0xffff) || (ch < '\x0080'))
                     {
                         break;
                     }
                     bytes[byteCount++] = (byte) ch;
                     index += 3;
                 }
                 Encoding encoding = Encoding.GetEncoding("utf-8", new EncoderReplacementFallback(""), new DecoderReplacementFallback(""));
                 char[] chars = new char[bytes.Length];
                 int charCount = encoding.GetChars(bytes, 0, byteCount, chars, 0);
                 if (charCount != 0)
                 {
                     start = index;
                     MatchUTF8Sequence(chRef, dest, ref destPosition, chars, charCount, bytes, isQuery, iriParsing);
                 }
                 else
                 {
                     if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
                     {
                         throw new UriFormatException(System.SR.GetString("net_uri_BadString"));
                     }
                     index = start + 3;
                     start = index;
                     dest[destPosition++] = (char) bytes[0];
                 }
             }
             if (index != end)
             {
                 goto Label_007F;
             }
             return dest;
         }
     }
     finally
     {
         chRef = null;
     }
     return dest;
 }
 private static unsafe char[] UnescapeString(string input, int start, int end, char[] dest, ref int destPosition, char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, bool isQuery, bool readOnlyConfig)
 {
     fixed (char* str = ((char*) input))
     {
         char* pStr = str;
         return UnescapeString(pStr, start, end, dest, ref destPosition, rsvd1, rsvd2, rsvd3, unescapeMode, syntax, isQuery, readOnlyConfig);
     }
 }
Example #9
0
        internal static unsafe void UnescapeString(char *pStr, int start, int end, ref ValueStringBuilder dest,
                                                   char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser?syntax, bool isQuery)
        {
            if ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.CopyOnly)
            {
                dest.Append(pStr + start, end - start);
                return;
            }

            bool escapeReserved = false;
            bool iriParsing     = Uri.IriParsingStatic(syntax) &&
                                  ((unescapeMode & UnescapeMode.EscapeUnescape) == UnescapeMode.EscapeUnescape);

            for (int next = start; next < end;)
            {
                char ch = (char)0;

                for (; next < end; ++next)
                {
                    if ((ch = pStr[next]) == '%')
                    {
                        if ((unescapeMode & UnescapeMode.Unescape) == 0)
                        {
                            // re-escape, don't check anything else
                            escapeReserved = true;
                        }
                        else if (next + 2 < end)
                        {
                            ch = DecodeHexChars(pStr[next + 1], pStr[next + 2]);
                            // Unescape a good sequence if full unescape is requested
                            if (unescapeMode >= UnescapeMode.UnescapeAll)
                            {
                                if (ch == Uri.c_DummyChar)
                                {
                                    if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
                                    {
                                        // Should be a rare case where the app tries to feed an invalid escaped sequence
                                        throw new UriFormatException(SR.net_uri_BadString);
                                    }
                                    continue;
                                }
                            }
                            // re-escape % from an invalid sequence
                            else if (ch == Uri.c_DummyChar)
                            {
                                if ((unescapeMode & UnescapeMode.Escape) != 0)
                                {
                                    escapeReserved = true;
                                }
                                else
                                {
                                    continue;   // we should throw instead but since v1.0 would just print '%'
                                }
                            }
                            // Do not unescape '%' itself unless full unescape is requested
                            else if (ch == '%')
                            {
                                next += 2;
                                continue;
                            }
                            // Do not unescape a reserved char unless full unescape is requested
                            else if (ch == rsvd1 || ch == rsvd2 || ch == rsvd3)
                            {
                                next += 2;
                                continue;
                            }
                            // Do not unescape a dangerous char unless it's V1ToStringFlags mode
                            else if ((unescapeMode & UnescapeMode.V1ToStringFlag) == 0 && IsNotSafeForUnescape(ch))
                            {
                                next += 2;
                                continue;
                            }
                            else if (iriParsing && ((ch <= '\x9F' && IsNotSafeForUnescape(ch)) ||
                                                    (ch > '\x9F' && !IriHelper.CheckIriUnicodeRange(ch, isQuery))))
                            {
                                // check if unenscaping gives a char outside iri range
                                // if it does then keep it escaped
                                next += 2;
                                continue;
                            }
                            // unescape escaped char or escape %
                            break;
                        }
                        else if (unescapeMode >= UnescapeMode.UnescapeAll)
                        {
                            if (unescapeMode >= UnescapeMode.UnescapeAllOrThrow)
                            {
                                // Should be a rare case where the app tries to feed an invalid escaped sequence
                                throw new UriFormatException(SR.net_uri_BadString);
                            }
                            // keep a '%' as part of a bogus sequence
                            continue;
                        }
                        else
                        {
                            escapeReserved = true;
                        }
                        // escape (escapeReserved==true) or otherwise unescape the sequence
                        break;
                    }
                    else if ((unescapeMode & (UnescapeMode.Unescape | UnescapeMode.UnescapeAll))
                             == (UnescapeMode.Unescape | UnescapeMode.UnescapeAll))
                    {
                        continue;
                    }
                    else if ((unescapeMode & UnescapeMode.Escape) != 0)
                    {
                        // Could actually escape some of the characters
                        if (ch == rsvd1 || ch == rsvd2 || ch == rsvd3)
                        {
                            // found an unescaped reserved character -> escape it
                            escapeReserved = true;
                            break;
                        }
                        else if ((unescapeMode & UnescapeMode.V1ToStringFlag) == 0 &&
                                 (ch <= '\x1F' || (ch >= '\x7F' && ch <= '\x9F')))
                        {
                            // found an unescaped reserved character -> escape it
                            escapeReserved = true;
                            break;
                        }
                    }
                }

                //copy off previous characters from input
                while (start < next)
                {
                    dest.Append(pStr[start++]);
                }

                if (next != end)
                {
                    if (escapeReserved)
                    {
                        EscapeAsciiChar((byte)pStr[next], ref dest);
                        escapeReserved = false;
                        next++;
                    }
                    else if (ch <= 127)
                    {
                        dest.Append(ch);
                        next += 3;
                    }
                    else
                    {
                        // Unicode
                        int charactersRead = PercentEncodingHelper.UnescapePercentEncodedUTF8Sequence(
                            pStr + next,
                            end - next,
                            ref dest,
                            isQuery,
                            iriParsing);

                        Debug.Assert(charactersRead > 0);
                        next += charactersRead;
                    }

                    start = next;
                }
            }
        }
Example #10
0
 internal static unsafe void UnescapeString(ReadOnlySpan <char> input, ref ValueStringBuilder dest,
                                            char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser?syntax, bool isQuery)
 {
     fixed(char *pStr = &MemoryMarshal.GetReference(input))
     {
         UnescapeString(pStr, 0, input.Length, ref dest, rsvd1, rsvd2, rsvd3, unescapeMode, syntax, isQuery);
     }
 }
Example #11
0
 //
 // This method will assume that any good Escaped Sequence will be unescaped in the output
 // - Assumes Dest.Length - detPosition >= end-start
 // - UnescapeLevel controls various modes of operation
 // - Any "bad" escape sequence will remain as is or '%' will be escaped.
 // - destPosition tells the starting index in dest for placing the result.
 //   On return destPosition tells the last character + 1 position in the "dest" array.
 // - The control chars and chars passed in rsdvX parameters may be re-escaped depending on UnescapeLevel
 // - It is a RARE case when Unescape actually needs escaping some characters mentioned above.
 //   For this reason it returns a char[] that is usually the same ref as the input "dest" value.
 //
 internal static unsafe void UnescapeString(string input, int start, int end, ref ValueStringBuilder dest,
                                            char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser?syntax, bool isQuery)
 {
     fixed(char *pStr = input)
     {
         UnescapeString(pStr, start, end, ref dest, rsvd1, rsvd2, rsvd3, unescapeMode, syntax, isQuery);
     }
 }
Example #12
0
        internal static unsafe char[] UnescapeString(char *pStr, int start, int end, char[] dest, ref int destPosition,
                                                     char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser?syntax, bool isQuery)
        {
            ValueStringBuilder vsb = new ValueStringBuilder(dest.Length);

            vsb.Append(dest.AsSpan(0, destPosition));
            UnescapeString(pStr, start, end, ref vsb, rsvd1, rsvd2, rsvd3, unescapeMode,
                           syntax, isQuery);

            if (vsb.Length > dest.Length)
            {
                dest = vsb.AsSpan().ToArray();
            }
            else
            {
                vsb.AsSpan(destPosition).TryCopyTo(dest.AsSpan(destPosition));
            }
            destPosition = vsb.Length;
            vsb.Dispose();
            return(dest);
        }
Example #13
0
        internal static char[] UnescapeString(string input, int start, int end, char[] dest, ref int destPosition, char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, bool isQuery) => default;      // 0x00000001809CB150-0x00000001809CB230

        internal static unsafe char[] UnescapeString(char *pStr, int start, int end, char[] dest, ref int destPosition, char rsvd1, char rsvd2, char rsvd3, UnescapeMode unescapeMode, UriParser syntax, bool isQuery) => default; // 0x00000001809CB230-0x00000001809CBC20