3333using System . IO ;
3434using System . Linq ;
3535using System . Text ;
36- using System . Web ;
3736using Xunit ;
3837
3938namespace System . Web . Tests
@@ -51,6 +50,8 @@ public class HttpUtilityTest
5150 new object [ ] { "<script>" , "<script>" } ,
5251 new object [ ] { ""a&b"" , "\" a&b\" " } ,
5352 new object [ ] { "'string'" , "'string'" } ,
53+ new object [ ] { "abc + def!" , "abc + def!" } ,
54+ new object [ ] { "This is an <element>!" , "This is an <element>!" } ,
5455 } ;
5556
5657 [ Theory ]
@@ -240,11 +241,9 @@ public void HtmlDecode_TextWriter(string decoded, string encoded)
240241 {
241242 "\u00A0 ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" ,
242243 @" ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" ,
243- } ,
244+ }
244245 } ;
245246
246-
247-
248247 [ Theory ]
249248 [ MemberData ( nameof ( HtmlEncodeDecodeData ) ) ]
250249 [ MemberData ( nameof ( HtmlEncodeData ) ) ]
@@ -254,6 +253,16 @@ public void HtmlEncode(string decoded, string encoded)
254253 Assert . Equal ( encoded , HttpUtility . HtmlEncode ( decoded ) ) ;
255254 }
256255
256+ [ Theory ]
257+ [ MemberData ( nameof ( HtmlEncodeDecodeData ) ) ]
258+ [ MemberData ( nameof ( HtmlEncodeData ) ) ]
259+ [ InlineData ( null , null ) ]
260+ [ InlineData ( 2 , "2" ) ]
261+ public void HtmlEncodeObject ( string decoded , string encoded )
262+ {
263+ Assert . Equal ( encoded , HttpUtility . HtmlEncode ( ( object ) decoded ) ) ;
264+ }
265+
257266 [ Theory ]
258267 [ MemberData ( nameof ( HtmlEncodeDecodeData ) ) ]
259268 [ MemberData ( nameof ( HtmlEncodeData ) ) ]
@@ -284,6 +293,8 @@ public static IEnumerable<object[]> JavaScriptStringEncodeData
284293 {
285294 yield return new object [ ] { null , "" } ;
286295 yield return new object [ ] { "" , "" } ;
296+ yield return new object [ ] { "No escaping needed." , "No escaping needed." } ;
297+ yield return new object [ ] { "The \t and \n will need to be escaped." , "The \\ t and \\ n will need to be escaped." } ;
287298 for ( char c = char . MinValue ; c < TestMaxChar ; c ++ )
288299 {
289300 if ( c >= 0 && c <= 7 || c == 11 || c >= 14 && c <= 31 || c == 38 || c == 39 || c == 60 || c == 62 || c == 133 || c == 8232 || c == 8233 )
@@ -365,10 +376,18 @@ private static string UnicodeStr
365376 new [ ] { new [ ] { UnicodeStr } }
366377 } ,
367378 new object [ ] { "name=value=test" , new [ ] { "name" } , new [ ] { new [ ] { "value=test" } } } ,
379+ new object [ ] { "name=valueé" , new [ ] { "name" , null } , new [ ] { new [ ] { "value" } , new [ ] { "#xe9;" } } } ,
380+ new object [ ] { "name=value&name2=value2" , new [ ] { "name" , "amp;name2" } , new [ ] { new [ ] { "value" } , new [ ] { "value2" } } } ,
381+ new object [ ] { "name=value=test+phrase" , new [ ] { "name" } , new [ ] { new [ ] { "value=test phrase" } } } ,
368382 } ;
369383
370384 public static IEnumerable < object [ ] > ParseQueryStringDataQ =>
371- ParseQueryStringData . Select ( a => new object [ ] { "?" + ( string ) a [ 0 ] } . Concat ( a . Skip ( 1 ) ) . ToArray ( ) ) ;
385+ ParseQueryStringData . Select ( a => new object [ ] { "?" + ( string ) a [ 0 ] } . Concat ( a . Skip ( 1 ) ) . ToArray ( ) )
386+ . Concat ( new [ ]
387+ {
388+ new object [ ] { "??name=value=test" , new [ ] { "?name" } , new [ ] { new [ ] { "value=test" } } } ,
389+ new object [ ] { "?" , Array . Empty < string > ( ) , Array . Empty < IList < string > > ( ) }
390+ } ) ;
372391
373392 [ Theory ]
374393 [ MemberData ( nameof ( ParseQueryStringData ) ) ]
@@ -407,10 +426,12 @@ public void ParseQueryString_Encoding_null()
407426 public void ParseQueryString_ToString ( )
408427 {
409428 var parsed = HttpUtility . ParseQueryString ( "" ) ;
429+ Assert . Empty ( parsed . ToString ( ) ) ;
410430 parsed . Add ( "ReturnUrl" , @"http://localhost/login/authenticate?ReturnUrl=http://localhost/secured_area&__provider__=google" ) ;
411431
412432 var expected = "ReturnUrl=http%3a%2f%2flocalhost%2flogin%2fauthenticate%3fReturnUrl%3dhttp%3a%2f%2flocalhost%2fsecured_area%26__provider__%3dgoogle" ;
413433 Assert . Equal ( expected , parsed . ToString ( ) ) ;
434+ Assert . Equal ( expected , HttpUtility . ParseQueryString ( expected ) . ToString ( ) ) ;
414435 }
415436
416437 #endregion ParseQueryString
@@ -428,6 +449,12 @@ public void ParseQueryString_ToString()
428449 new object [ ] { "http://127.0.0.1:8080/appDir/page.aspx?foo=bar" , "http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r" } ,
429450 new object [ ] { "http://127.0.0.1:8080/appDir/page.aspx?foo=b%ar" , "http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r" } ,
430451 new object [ ] { "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r" , "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r" } ,
452+ new object [ ] { "http://127.0.0.1:8080/appDir/page.aspx?foo=bar baz" , "http://127.0.0.1:8080/appDir/page.aspx?foo=bar+baz" } ,
453+ new object [ ] { "http://example.net/\U00010000 " , "http://example.net/\U00010000 " } ,
454+ new object [ ] { "http://example.net/\uFFFD " , "http://example.net/\uD800 " } ,
455+ new object [ ] { "http://example.net/\uFFFD a" , "http://example.net/\uD800 a" } ,
456+ new object [ ] { "http://example.net/\uFFFD " , "http://example.net/\uDC00 " } ,
457+ new object [ ] { "http://example.net/\uFFFD a" , "http://example.net/\uDC00 a" }
431458 } ;
432459
433460 public static IEnumerable < object [ ] > UrlDecodeDataToBytes =>
@@ -441,6 +468,12 @@ public void ParseQueryString_ToString()
441468 new object [ ] { "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r" , "http://127.0.0.1:8080/appDir/page.aspx?foo=b%uu0061r" } ,
442469 new object [ ] { "http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r" , "http://127.0.0.1:8080/appDir/page.aspx?foo=b%u0061r" } ,
443470 new object [ ] { "http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r" , "http://127.0.0.1:8080/appDir/page.aspx?foo=b%%u0061r" } ,
471+ new object [ ] { "http://127.0.0.1:8080/appDir/page.aspx?foo=bar baz" , "http://127.0.0.1:8080/appDir/page.aspx?foo=bar+baz" } ,
472+ new object [ ] { "http://example.net/\U00010000 " , "http://example.net/\U00010000 " } ,
473+ new object [ ] { "http://example.net/\uFFFD " , "http://example.net/\uD800 " } ,
474+ new object [ ] { "http://example.net/\uFFFD a" , "http://example.net/\uD800 a" } ,
475+ new object [ ] { "http://example.net/\uFFFD " , "http://example.net/\uDC00 " } ,
476+ new object [ ] { "http://example.net/\uFFFD a" , "http://example.net/\uDC00 a" }
444477 } ;
445478
446479 [ Theory ]
@@ -450,13 +483,60 @@ public void UrlDecode(string decoded, string encoded)
450483 Assert . Equal ( decoded , HttpUtility . UrlDecode ( encoded ) ) ;
451484 }
452485
486+ [ Fact ]
487+ public void UrlDecode_null ( )
488+ {
489+ Assert . Null ( HttpUtility . UrlDecode ( default ( string ) , Encoding . UTF8 ) ) ;
490+ Assert . Null ( HttpUtility . UrlDecode ( default ( byte [ ] ) , Encoding . UTF8 ) ) ;
491+ Assert . Null ( HttpUtility . UrlDecode ( null ) ) ;
492+ Assert . Null ( HttpUtility . UrlDecode ( null , 2 , 0 , Encoding . UTF8 ) ) ;
493+ Assert . Throws < ArgumentNullException > ( "bytes" , ( ) => HttpUtility . UrlDecode ( null , 2 , 3 , Encoding . UTF8 ) ) ;
494+ }
495+
496+ [ Fact ]
497+ public void UrlDecode_OutOfRange ( )
498+ {
499+ byte [ ] bytes = { 0 , 1 , 2 } ;
500+ Assert . Throws < ArgumentOutOfRangeException > ( "offset" , ( ) => HttpUtility . UrlDecode ( bytes , - 1 , 2 , Encoding . UTF8 ) ) ;
501+ Assert . Throws < ArgumentOutOfRangeException > ( "offset" , ( ) => HttpUtility . UrlDecode ( bytes , 14 , 2 , Encoding . UTF8 ) ) ;
502+ Assert . Throws < ArgumentOutOfRangeException > ( "count" , ( ) => HttpUtility . UrlDecode ( bytes , 1 , 12 , Encoding . UTF8 ) ) ;
503+ Assert . Throws < ArgumentOutOfRangeException > ( "count" , ( ) => HttpUtility . UrlDecode ( bytes , 1 , - 12 , Encoding . UTF8 ) ) ;
504+ }
505+
453506 [ Theory ]
454507 [ MemberData ( nameof ( UrlDecodeDataToBytes ) ) ]
455508 public void UrlDecodeToBytes ( string decoded , string encoded )
456509 {
457510 Assert . Equal ( decoded , Encoding . UTF8 . GetString ( HttpUtility . UrlDecodeToBytes ( encoded , Encoding . UTF8 ) ) ) ;
458511 }
459512
513+ [ Theory ]
514+ [ MemberData ( nameof ( UrlDecodeDataToBytes ) ) ]
515+ public void UrlDecodeToBytes_DefaultEncoding ( string decoded , string encoded )
516+ {
517+ Assert . Equal ( decoded , Encoding . UTF8 . GetString ( HttpUtility . UrlDecodeToBytes ( encoded ) ) ) ;
518+ }
519+
520+ [ Fact ]
521+ public void UrlDecodeToBytes_null ( )
522+ {
523+ Assert . Null ( HttpUtility . UrlDecodeToBytes ( default ( byte [ ] ) ) ) ;
524+ Assert . Null ( HttpUtility . UrlDecodeToBytes ( default ( string ) ) ) ;
525+ Assert . Null ( HttpUtility . UrlDecodeToBytes ( default ( string ) , Encoding . UTF8 ) ) ;
526+ Assert . Null ( HttpUtility . UrlDecodeToBytes ( default ( byte [ ] ) , 2 , 0 ) ) ;
527+ Assert . Throws < ArgumentNullException > ( "bytes" , ( ) => HttpUtility . UrlDecodeToBytes ( default ( byte [ ] ) , 2 , 3 ) ) ;
528+ }
529+
530+ [ Fact ]
531+ public void UrlDecodeToBytes_OutOfRange ( )
532+ {
533+ byte [ ] bytes = { 0 , 1 , 2 } ;
534+ Assert . Throws < ArgumentOutOfRangeException > ( "offset" , ( ) => HttpUtility . UrlDecodeToBytes ( bytes , - 1 , 2 ) ) ;
535+ Assert . Throws < ArgumentOutOfRangeException > ( "offset" , ( ) => HttpUtility . UrlDecodeToBytes ( bytes , 14 , 2 ) ) ;
536+ Assert . Throws < ArgumentOutOfRangeException > ( "count" , ( ) => HttpUtility . UrlDecodeToBytes ( bytes , 1 , 12 ) ) ;
537+ Assert . Throws < ArgumentOutOfRangeException > ( "count" , ( ) => HttpUtility . UrlDecodeToBytes ( bytes , 1 , - 12 ) ) ;
538+ }
539+
460540 [ Theory ]
461541 [ MemberData ( nameof ( UrlDecodeData ) ) ]
462542 public void UrlDecode_ByteArray ( string decoded , string encoded )
@@ -529,10 +609,57 @@ public void UrlEncodeToBytes(string decoded, string encoded)
529609 Assert . Equal ( encoded , Encoding . UTF8 . GetString ( HttpUtility . UrlEncodeToBytes ( decoded , Encoding . UTF8 ) ) ) ;
530610 }
531611
612+ [ Theory ]
613+ [ MemberData ( nameof ( UrlEncodeData ) ) ]
614+ public void UrlEncodeToBytes_DefaultEncoding ( string decoded , string encoded )
615+ {
616+ Assert . Equal ( encoded , Encoding . UTF8 . GetString ( HttpUtility . UrlEncodeToBytes ( decoded ) ) ) ;
617+ }
618+
619+ [ Theory , MemberData ( nameof ( UrlEncodeData ) ) ]
620+ public void UrlEncodeToBytesExplicitSize ( string decoded , string encoded )
621+ {
622+ byte [ ] bytes = Encoding . UTF8 . GetBytes ( decoded ) ;
623+ Assert . Equal ( encoded , Encoding . UTF8 . GetString ( HttpUtility . UrlEncodeToBytes ( bytes , 0 , bytes . Length ) ) ) ;
624+ }
625+
626+
627+ [ Theory ]
628+ [ InlineData ( " abc defgh" , "abc+def" , 1 , 7 ) ]
629+ [ InlineData ( " abc defgh" , "" , 1 , 0 ) ]
630+ public void UrlEncodeToBytesExplicitSize ( string decoded , string encoded , int offset , int count )
631+ {
632+ byte [ ] bytes = Encoding . UTF8 . GetBytes ( decoded ) ;
633+ Assert . Equal ( encoded , Encoding . UTF8 . GetString ( HttpUtility . UrlEncodeToBytes ( bytes , offset , count ) ) ) ;
634+ }
635+
636+ [ Theory ]
637+ [ InlineData ( "abc def" , " abc+defgh" , 1 , 7 ) ]
638+ [ InlineData ( "" , " abc defgh" , 1 , 0 ) ]
639+ public void UrlDecodeToBytesExplicitSize ( string decoded , string encoded , int offset , int count )
640+ {
641+ byte [ ] bytes = Encoding . UTF8 . GetBytes ( encoded ) ;
642+ Assert . Equal ( decoded , Encoding . UTF8 . GetString ( HttpUtility . UrlDecodeToBytes ( bytes , offset , count ) ) ) ;
643+ }
644+
532645 [ Fact ]
533646 public void UrlEncodeToBytes_null ( )
534647 {
535648 Assert . Null ( HttpUtility . UrlEncodeToBytes ( null , Encoding . UTF8 ) ) ;
649+ Assert . Null ( HttpUtility . UrlEncodeToBytes ( default ( byte [ ] ) ) ) ;
650+ Assert . Null ( HttpUtility . UrlEncodeToBytes ( default ( string ) ) ) ;
651+ Assert . Null ( HttpUtility . UrlEncodeToBytes ( null , 2 , 0 ) ) ;
652+ Assert . Throws < ArgumentNullException > ( "bytes" , ( ) => HttpUtility . UrlEncodeToBytes ( null , 2 , 3 ) ) ;
653+ }
654+
655+ [ Fact ]
656+ public void UrlEncodeToBytes_OutOfRange ( )
657+ {
658+ byte [ ] bytes = { 0 , 1 , 2 } ;
659+ Assert . Throws < ArgumentOutOfRangeException > ( "offset" , ( ) => HttpUtility . UrlEncodeToBytes ( bytes , - 1 , 2 ) ) ;
660+ Assert . Throws < ArgumentOutOfRangeException > ( "offset" , ( ) => HttpUtility . UrlEncodeToBytes ( bytes , 14 , 2 ) ) ;
661+ Assert . Throws < ArgumentOutOfRangeException > ( "count" , ( ) => HttpUtility . UrlEncodeToBytes ( bytes , 1 , 12 ) ) ;
662+ Assert . Throws < ArgumentOutOfRangeException > ( "count" , ( ) => HttpUtility . UrlEncodeToBytes ( bytes , 1 , - 12 ) ) ;
536663 }
537664
538665 [ Theory ]
@@ -543,9 +670,22 @@ public void UrlEncode_ByteArray(string decoded, string encoded)
543670 }
544671
545672 [ Fact ]
546- public void UrlEncode_ByteArray_null ( )
673+ public void UrlEncode_null ( )
674+ {
675+ Assert . Null ( HttpUtility . UrlEncode ( ( byte [ ] ) null ) ) ;
676+ Assert . Null ( HttpUtility . UrlEncode ( ( string ) null ) ) ;
677+ Assert . Null ( HttpUtility . UrlEncode ( null , Encoding . UTF8 ) ) ;
678+ Assert . Null ( HttpUtility . UrlEncode ( null , 2 , 3 ) ) ;
679+ }
680+
681+ [ Fact ]
682+ public void UrlEncode_OutOfRange ( )
547683 {
548- Assert . Null ( HttpUtility . UrlEncode ( ( byte [ ] ) null ) ) ;
684+ byte [ ] bytes = { 0 , 1 , 2 } ;
685+ Assert . Throws < ArgumentOutOfRangeException > ( "offset" , ( ) => HttpUtility . UrlEncode ( bytes , - 1 , 2 ) ) ;
686+ Assert . Throws < ArgumentOutOfRangeException > ( "offset" , ( ) => HttpUtility . UrlEncode ( bytes , 14 , 2 ) ) ;
687+ Assert . Throws < ArgumentOutOfRangeException > ( "count" , ( ) => HttpUtility . UrlEncode ( bytes , 1 , 12 ) ) ;
688+ Assert . Throws < ArgumentOutOfRangeException > ( "count" , ( ) => HttpUtility . UrlEncode ( bytes , 1 , - 12 ) ) ;
549689 }
550690
551691 #endregion UrlEncode(ToBytes)
@@ -591,6 +731,15 @@ public void UrlEncodeUnicodeToBytes(string decoded, string encoded)
591731 [ InlineData ( " " , "%20" ) ]
592732 [ InlineData ( "\n " , "%0a" ) ]
593733 [ InlineData ( "default.xxx?sdsd=sds" , "default.xxx?sdsd=sds" ) ]
734+ [ InlineData ( "?sdsd=sds" , "?sdsd=sds" ) ]
735+ [ InlineData ( "" , "" ) ]
736+ [ InlineData ( "http://example.net/default.xxx?sdsd=sds" , "http://example.net/default.xxx?sdsd=sds" ) ]
737+ [ InlineData ( "http://example.net:8080/default.xxx?sdsd=sds" , "http://example.net:8080/default.xxx?sdsd=sds" ) ]
738+ [ InlineData ( "http://eXample.net:80/default.xxx?sdsd=sds" , "http://eXample.net:80/default.xxx?sdsd=sds" ) ]
739+ [ InlineData ( "http://EXAMPLE.NET/default.xxx?sdsd=sds" , "http://EXAMPLE.NET/default.xxx?sdsd=sds" ) ]
740+ [ InlineData ( "http://EXAMPLE.NET/défault.xxx?sdsd=sds" , "http://EXAMPLE.NET/d%c3%a9fault.xxx?sdsd=sds" ) ]
741+ [ InlineData ( "file:///C/Users" , "file:///C/Users" ) ]
742+ [ InlineData ( "mailto:user@example.net" , "mailto:user@example.net" ) ]
594743 public void UrlPathEncode ( string decoded , string encoded )
595744 {
596745 Assert . Equal ( encoded , HttpUtility . UrlPathEncode ( decoded ) ) ;
0 commit comments