Make WordPress Core

Opened 9 years ago

Closed 9 years ago

#34958 closed defect (bug) (invalid)

esc_url() and parse_url() do not work together.

Reported by: damiankaelgreen's profile damiankaelgreen Owned by:
Milestone: Priority: normal
Severity: normal Version: 4.4
Component: Formatting Keywords: reporter-feedback
Focuses: Cc:


Here is a strange anomaly that I just discovered. It seems that WP's esc_url() is modifying characters in a stringified url, somehow, ever so slightly, such that PHP's parse_url() can not parse it correctly.

Here's the sample code:

echo "PHP version: ".phpversion()."<br>";
global $wp_version;
echo "WP version (4.4.0): ".$wp_version."<br>";
$my_orig_url = '/?empty_username=1&empty_email=1#register';
echo "-1---------Original URL as str----------:<br>".$my_orig_url."<br>";
$my_esc_url = esc_url($my_orig_url);
echo "-2---------Esc_URL as str----------:<br>".$my_esc_url."<br>";
$query_str_orig = parse_url($my_orig_url);
echo "-3--------CORRECT (query_str_orig after parse_url)--------:<br>";
echo "<br>";
$query_str_esc = parse_url($my_esc_url);
echo "-4---------WRONG (query_str_esc after parse_url)---------:<br>";
echo "<br>---------------END-----------------<br>";


PHP version: 5.6.16
WP version (4.4.0): 4.4
-1---------Original URL as str----------:
-2---------Esc_URL as str----------:
-3--------CORRECT (query_str_orig after parse_url)--------:
Array ( [path] => / [query] => empty_username=1&empty_email=1 [fragment] => register ) 
-4---------WRONG (query_str_esc after parse_url)---------:
Array ( [path] => / [query] => empty_username=1& [fragment] => 038;empty_email=1#register ) 

Truthfully, I don't know if this is the fault of the esc_url() or the parse_url() function definition, but if it turns out to be a problem with the PHP's parse_url, then I think perhaps a possible quick fix might be to amend WP's brand new wp_parse_url() function (as of v 4.4.0) which looks like it is intended to handle PHP fringe issues with parse_url() just like this. On the other hand, it could very well be an esc_url() issue. I haven't yet been able to identify what characters have changed...

Note: This also happened on a previous version of WP 4.3.7 I think it was...

Change History (2)

#1 @johnbillion
9 years ago

  • Component changed from General to Formatting
  • Keywords reporter-feedback added

Thanks for the report, @damiankaelgreen .

This is expected behaviour, as esc_url() escapes the ampersand in the URL, converting it to &#038;. parse_url() is not intended to work with escaped ampersands.

It may be that you should be using esc_url_raw() in this particular case, as esc_url() is meant to be used late to escape a URL for output.

#2 @dd32
9 years ago

  • Milestone Awaiting Review deleted
  • Resolution set to invalid
  • Status changed from new to closed

as above, esc_url() is designed for outputting within HTML, as such it escapes & to the HTML entity &#038; to conform to XHTML specifications.

esc_url_raw() can be used when the url is to be used programmatically (such as by parse_url() or within a header() call)

Note: See TracTickets for help on using tickets.