@@ -41,20 +41,22 @@ class Uri implements UriInterface
4141 public function __construct (string $ uri = '' )
4242 {
4343 if ('' !== $ uri ) {
44- if (false === $ parts = \parse_url ($ uri )) {
44+ $ encodedUri = \preg_replace_callback ('/[^\x00-\x7F]++/ ' , [__CLASS__ , 'rawurlencodeMatchZero ' ], $ uri );
45+ if (false === $ parts = \parse_url ($ encodedUri )) {
4546 throw new \InvalidArgumentException (\sprintf ('Unable to parse URI: "%s" ' , $ uri ));
4647 }
4748
4849 // Apply parse_url parts to a URI.
4950 $ this ->scheme = isset ($ parts ['scheme ' ]) ? \strtr ($ parts ['scheme ' ], 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' , 'abcdefghijklmnopqrstuvwxyz ' ) : '' ;
50- $ this ->userInfo = $ parts ['user ' ] ?? '' ;
51- $ this ->host = isset ($ parts ['host ' ]) ? \strtr ($ parts ['host ' ], 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' , 'abcdefghijklmnopqrstuvwxyz ' ) : '' ;
51+ $ this ->userInfo = isset ($ parts ['user ' ]) ? \rawurldecode ($ parts ['user ' ]) : '' ;
52+ $ host = isset ($ parts ['host ' ]) ? \rawurldecode ($ parts ['host ' ]) : '' ;
53+ $ this ->host = \strtr ($ host , 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' , 'abcdefghijklmnopqrstuvwxyz ' );
5254 $ this ->port = isset ($ parts ['port ' ]) ? $ this ->filterPort ($ parts ['port ' ]) : null ;
5355 $ this ->path = isset ($ parts ['path ' ]) ? $ this ->filterPath ($ parts ['path ' ]) : '' ;
5456 $ this ->query = isset ($ parts ['query ' ]) ? $ this ->filterQueryAndFragment ($ parts ['query ' ]) : '' ;
5557 $ this ->fragment = isset ($ parts ['fragment ' ]) ? $ this ->filterQueryAndFragment ($ parts ['fragment ' ]) : '' ;
5658 if (isset ($ parts ['pass ' ])) {
57- $ this ->userInfo .= ': ' . $ parts ['pass ' ];
59+ $ this ->userInfo .= ': ' . \rawurldecode ( $ parts ['pass ' ]) ;
5860 }
5961 }
6062 }
@@ -315,17 +317,11 @@ private function filterPath($path): string
315317 throw new \InvalidArgumentException ('Path must be a string ' );
316318 }
317319
318- $ result = \preg_replace_callback (
319- '/(?:[^ ' . self ::CHAR_UNRESERVED . self ::CHAR_SUB_DELIMS . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/u ' ,
320+ return \preg_replace_callback (
321+ '/(?:[^ ' . self ::CHAR_UNRESERVED . self ::CHAR_SUB_DELIMS . '%:@\/]++|%(?![A-Fa-f0-9]{2}))/ ' ,
320322 [__CLASS__ , 'rawurlencodeMatchZero ' ],
321323 $ path
322324 );
323-
324- if ($ result === null ) {
325- throw new \InvalidArgumentException ('Invalid UTF-8 sequence in path ' );
326- }
327-
328- return $ result ;
329325 }
330326
331327 private function filterQueryAndFragment ($ str ): string
@@ -334,17 +330,11 @@ private function filterQueryAndFragment($str): string
334330 throw new \InvalidArgumentException ('Query and fragment must be a string ' );
335331 }
336332
337- $ result = \preg_replace_callback (
338- '/(?:[^ ' . self ::CHAR_UNRESERVED . self ::CHAR_SUB_DELIMS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/u ' ,
333+ return \preg_replace_callback (
334+ '/(?:[^ ' . self ::CHAR_UNRESERVED . self ::CHAR_SUB_DELIMS . '%:@\/\?]++|%(?![A-Fa-f0-9]{2}))/ ' ,
339335 [__CLASS__ , 'rawurlencodeMatchZero ' ],
340336 $ str
341337 );
342-
343- if ($ result === null ) {
344- throw new \InvalidArgumentException ('Invalid UTF-8 sequence in query/fragment ' );
345- }
346-
347- return $ result ;
348338 }
349339
350340 private static function rawurlencodeMatchZero (array $ match ): string
0 commit comments