Skip to content

Commit ab0f628

Browse files
committed
Refine logic for URL validation
1 parent dd77e6f commit ab0f628

File tree

1 file changed

+15
-22
lines changed

1 file changed

+15
-22
lines changed

includes/Traits/URL_Utils.php

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -36,39 +36,32 @@ protected function is_valid_url( string $url ): bool {
3636
return false;
3737
}
3838

39-
// Must have a valid scheme and host, and scheme must be http or https.
39+
// Must have a valid scheme and host.
4040
if ( empty( $parsed_url['scheme'] ) || empty( $parsed_url['host'] ) ) {
4141
return false;
4242
}
4343

44-
if ( ! in_array( $parsed_url['scheme'], array( 'http', 'https' ), true ) ) {
44+
// Validate host doesn't contain obviously invalid characters.
45+
// Allow alphanumeric, dots, hyphens, and underscores (for localhost, etc.).
46+
if ( preg_match( '/[^a-z0-9.\-_]/i', $parsed_url['host'] ) ) {
4547
return false;
4648
}
4749

48-
// Check for duplicated protocol and invalid host characters.
49-
return $this->validate_url_structure( $url, $parsed_url );
50-
}
51-
52-
/**
53-
* Validates URL structure for duplicated protocols and invalid host characters.
54-
*
55-
* @since 1.6.0
56-
*
57-
* @param string $url The full URL.
58-
* @param array $parsed_url Parsed URL array.
59-
* @return bool true if the URL structure is valid, otherwise false.
60-
*/
61-
private function validate_url_structure( string $url, array $parsed_url ): bool {
6250
// Detect duplicated protocol in the host/path portion (e.g., "https://http://example.com/").
6351
// Only check up to the query string to avoid false positives with URLs in query parameters.
64-
$url_without_query = strtok( $url, '?' );
65-
if ( false !== $url_without_query && str_contains( substr( $url_without_query, strlen( $parsed_url['scheme'] ) + 3 ), '://' ) ) {
66-
return false;
52+
$query_position = strpos( $url, '?' );
53+
54+
if ( false !== $query_position ) {
55+
$url_without_query = substr( $url, 0, $query_position );
56+
} else {
57+
$url_without_query = $url;
6758
}
6859

69-
// Validate host doesn't contain obviously invalid characters.
70-
// Allow alphanumeric, dots, hyphens, and underscores (for localhost, etc.).
71-
if ( preg_match( '/[^a-z0-9.\-_]/i', $parsed_url['host'] ) ) {
60+
// Check for duplicated protocol after the scheme:// portion.
61+
$scheme_length = strlen( $parsed_url['scheme'] );
62+
$after_scheme = substr( $url_without_query, $scheme_length + 3 );
63+
64+
if ( str_contains( $after_scheme, '://' ) ) {
7265
return false;
7366
}
7467

0 commit comments

Comments
 (0)