@@ -514,29 +514,37 @@ private static function resolveUrl(array $url, ?array $base, array $queryDefault
514514 */
515515 private static function parseUrl (string $ url , array $ query = [], array $ allowedSchemes = ['http ' => 80 , 'https ' => 443 ]): array
516516 {
517- if (false === $ parts = parse_url ($ url )) {
518- if ('/ ' !== ($ url [0 ] ?? '' ) || false === $ parts = parse_url ($ url .'# ' )) {
519- throw new InvalidArgumentException (sprintf ('Malformed URL "%s". ' , $ url ));
520- }
521- unset($ parts ['fragment ' ]);
517+ $ tail = '' ;
518+
519+ if (false === $ parts = parse_url (\strlen ($ url ) !== strcspn ($ url , '?# ' ) ? $ url : $ url .$ tail = '# ' )) {
520+ throw new InvalidArgumentException (sprintf ('Malformed URL "%s". ' , $ url ));
522521 }
523522
524523 if ($ query ) {
525524 $ parts ['query ' ] = self ::mergeQueryString ($ parts ['query ' ] ?? null , $ query , true );
526525 }
527526
527+ $ scheme = $ parts ['scheme ' ] ?? null ;
528+ $ host = $ parts ['host ' ] ?? null ;
529+
530+ if (!$ scheme && $ host && !str_starts_with ($ url , '// ' )) {
531+ $ parts = parse_url (':/ ' .$ url .$ tail );
532+ $ parts ['path ' ] = substr ($ parts ['path ' ], 2 );
533+ $ scheme = $ host = null ;
534+ }
535+
528536 $ port = $ parts ['port ' ] ?? 0 ;
529537
530- if (null !== $ scheme = $ parts [ ' scheme ' ] ?? null ) {
538+ if (null !== $ scheme ) {
531539 if (!isset ($ allowedSchemes [$ scheme = strtolower ($ scheme )])) {
532- throw new InvalidArgumentException (sprintf ('Unsupported scheme in "%s". ' , $ url ));
540+ throw new InvalidArgumentException (sprintf ('Unsupported scheme in "%s": "%s" expected . ' , $ url, implode ( ' " or " ' , array_keys ( $ allowedSchemes )) ));
533541 }
534542
535543 $ port = $ allowedSchemes [$ scheme ] === $ port ? 0 : $ port ;
536544 $ scheme .= ': ' ;
537545 }
538546
539- if (null !== $ host = $ parts [ ' host ' ] ?? null ) {
547+ if (null !== $ host ) {
540548 if (!\defined ('INTL_IDNA_VARIANT_UTS46 ' ) && preg_match ('/[\x80-\xFF]/ ' , $ host )) {
541549 throw new InvalidArgumentException (sprintf ('Unsupported IDN "%s", try enabling the "intl" PHP extension or running "composer require symfony/polyfill-intl-idn". ' , $ host ));
542550 }
@@ -564,7 +572,7 @@ private static function parseUrl(string $url, array $query = [], array $allowedS
564572 'authority ' => null !== $ host ? '// ' .(isset ($ parts ['user ' ]) ? $ parts ['user ' ].(isset ($ parts ['pass ' ]) ? ': ' .$ parts ['pass ' ] : '' ).'@ ' : '' ).$ host : null ,
565573 'path ' => isset ($ parts ['path ' ][0 ]) ? $ parts ['path ' ] : null ,
566574 'query ' => isset ($ parts ['query ' ]) ? '? ' .$ parts ['query ' ] : null ,
567- 'fragment ' => isset ($ parts ['fragment ' ]) ? '# ' .$ parts ['fragment ' ] : null ,
575+ 'fragment ' => isset ($ parts ['fragment ' ]) && ! $ tail ? '# ' .$ parts ['fragment ' ] : null ,
568576 ];
569577 }
570578
0 commit comments