[wp-trac] [WordPress Trac] #52886: Update esc_url to allow for specifying an https:// as default protocol

WordPress Trac noreply at wordpress.org
Tue Sep 7 02:58:03 UTC 2021


#52886: Update esc_url to allow for specifying an https:// as default protocol
-------------------------------------------------+-------------------------
 Reporter:  mkaz                                 |       Owner:  (none)
     Type:  enhancement                          |      Status:  new
 Priority:  normal                               |   Milestone:  Future
                                                 |  Release
Component:  Formatting                           |     Version:
 Severity:  normal                               |  Resolution:
 Keywords:  has-patch needs-unit-tests needs-    |     Focuses:
  dev-note                                       |
-------------------------------------------------+-------------------------

Comment (by costdev):

 @SergeyBiryukov
 > Looking at this again, I wonder if it's straightforward enough in
 practice, as it would require passing > four parameters to every esc_url()
 call that might be missing the protocol and should default to
 > https://. If the site is known to use https://, that seems redundant.

 In this case, would
 `wp_is_using_https()`[https://developer.wordpress.org/reference/functions/wp_is_using_https/
 Docs] be appropriate regarding "known to use `https://`" as it tests the
 home and site URLs?

 If so, an adjustment could be made to the latest patch:

 {{{#!php lineno=4291 marks=4307-4309,4314,4317-4319
 <?php

 /**
  * Checks and cleans a URL.
  *
  * A number of characters are removed from the URL. If the URL is for
 displaying
  * (the default behaviour) ampersands are also replaced. The {@see
 'clean_url'} filter
  * is applied to the returned cleaned URL.
  *
  * @since 2.8.0
  * @since 5.8.0 Added the `$default_protocol` parameter.
  *
  * @param string   $url              The URL to be cleaned.
  * @param string[] $protocols        Optional. An array of acceptable
 protocols.
  *                                   Defaults to return value of
 wp_allowed_protocols().
  * @param string   $_context         Private. Use esc_url_raw() for
 database usage.
  * @param string   $default_protocol Optional. Use to specify different
 default protocol.
  *                                   Defaults to http:// or https:// based
 on the result
   *                                  of is_wp_using_https().
  * @return string The cleaned URL after the {@see 'clean_url'} filter is
 applied.
  *                An empty string is returned if `$url` specifies a
 protocol other than
  *                those in `$protocols`, or if `$url` contains an empty
 string.
  */
 function esc_url( $url, $protocols = null, $_context = 'display',
 $default_protocol = '' ) {
         $original_url = $url;

         if ( '' === $default_protocol ) {
                 $default_protocol = ( wp_is_using_https() ) ? 'https://' :
 'http://';
         }

         if ( '' === $url ) {
                 return $url;
         }

         $url = str_replace( ' ', '%20', ltrim( $url ) );
         $url = preg_replace(
 '|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\[\]\\x80-\\xff]|i', '', $url );

         if ( '' === $url ) {
                 return $url;
         }

         if ( 0 !== stripos( $url, 'mailto:' ) ) {
                 $strip = array( '%0d', '%0a', '%0D', '%0A' );
                 $url   = _deep_replace( $strip, $url );
         }

         $url = str_replace( ';//', '://', $url );
         /*
          * If the URL doesn't appear to contain a scheme, we presume
          * it needs http:// prepended (unless it's a relative link
          * starting with /, # or ?, or a PHP file).
          * Since 5.8, it uses $default_protocol to allow https://
 presumption
          */
         if ( strpos( $url, ':' ) === false && ! in_array( $url[0], array(
 '/', '#', '?' ), true ) &&
                 ! preg_match( '/^[a-z0-9-]+?\.php/i', $url ) ) {
                 $url = $default_protocol . $url;
         }

         // Replace ampersands and single quotes only when displaying.

 }}}

 This adjustment:

 1. still appears to meet the aims of the ticket without requiring a change
 to existing `esc_url()` calls.
 2. seems to remove the redundancy @SergeyBiryukov raised.
 3. doesn't assume that `http://` should be the default protocol.
 4. will mean that `esc_url()` automatically adapts when a website is
 updated to support `https://`.

 **Questions**

 1. If `wp_is_using_https()` isn't appropriate because we only need to test
 one of the URLs, would it be `wp_is_home_url_using_https()`
 [https://developer.wordpress.org/reference/functions/wp_is_home_url_using_https/
 Docs] or `wp_is_site_url_using_https()`
 [https://developer.wordpress.org/reference/functions/wp_is_site_url_using_https/
 Docs]?

 2. If `wp_is_using_https()` isn't appropriate because it fails to
 sufficiently check the `https://` status for this issue, would
 `wp_is_https_supported()`
 [https://developer.wordpress.org/reference/functions/wp_is_https_supported/
 Docs] be more appropriate? Or is there another that stands out as
 appropriate?

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/52886#comment:9>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list