WordPress.org

Make WordPress Core

Opened 20 months ago

Last modified 19 months ago

#36663 new defect (bug)

Wordpress 4.5 Query Strings Replacing "." with "_"

Reported by: michael.bucklin Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.5
Component: Administration Keywords: reporter-feedback
Focuses: Cc:

Description

As of Wordpress 4.5, any query strings using a "." will get converted to a "_". While i understand that PHP doesn't support a period in a query string value, there are instances where query strings with periods are used by JavaScript and need to be retained. For example, the Webtrends analytics platform uses periods in most of their analytics query string values. For example, they use "wt.mc_id", "wt.z_mce", and "wt.dl".

It appears that changes to 'wp-includes/canonical.php' in 4.5 cause these periods to be visually and functionally converted to underscores when the pages loads. Interestingly, this only happens on pages and not posts.

Can we get the functionality put back the way it was so that the periods are retained, as this update will break Webtrends functionality, as well as any site using JavaScript that expects a period in a query string value?

Change History (9)

#1 @swissspidy
20 months ago

  • Focuses javascript performance removed

#2 @swissspidy
20 months ago

  • Keywords reporter-feedback added

I just tested this on a local site running WordPress 3.9 and even there ?wt.mc_id=wt.mc_id turns into array(1) { ["wt_mc_id"]=> string(8) "wt.mc_id" }.

Are you sure this has been working until WordPress 4.5? It looks like standard PHP behaviour to me, see https://bugs.php.net/bug.php?id=45272 for example. Which version of PHP are you using?

#3 @michael.bucklin
20 months ago

You are correct that it gets converted in that PHP array, but if you look at the site URL the value "wt.mc_id" stays in the address bar. As of 4.5, the value in the address bar actually gets changed to use the underscore, "wt_mc_id". I downloaded 4.4.2 and tested and the behavior does not occur in that version.

#4 @swissspidy
20 months ago

  • Component changed from Canonical to Administration

@michael.bucklin Ah, it happens in the admin, gotcha!

Query args aren't modified in the front-end, but wp_admin_canonical_url() is run in the admin to remove query args like ?message on page load.

The culprit is this line in the function:

$current_url  = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );

Here, $_SERVER['REQUEST_URI'] contains the wrong information. No idea where the query var gets modified though...

#5 @michael.bucklin
20 months ago

I may have not been explaining the issue well enough, i apologize for that. Here is a little more information. To reproduce:

1) Install a fresh copy of 4.4.2
2) Log in to the dashboard
3) Go to 'settings', 'reading', and set the front page display to static page. I chose the Sample page that comes with a fresh install.
4) Pull up the site, but append the following query string to the URL ?wt.mc_id=foobar.

Observe that in the URL bar, the value '?wt.mc_id=foobar' is retained as is.

5) Now upgrade to 4.5 in the dashboard.
6) Again go to the site with the query string '?wt.mc_id=foobar' appended to the site URL

Observe that the value 'wt.mc_id' is changed to 'wt_mc_id'. The period is changed to an underscore, which breaks the JavaScript that is looking for a value with the period. I can't change the JavaScript as it is from a well known analytics platform, Webtrends.

---

Digging through the Wordpress code and what changed, i isolated the issue to line 176 of wp-includes/canonical.php, which in 4.5 reads:

} elseif ( is_page() && !is_feed() && 'page' == get_option('show_on_front') && get_queried_object_id() == get_option('page_on_front') && ! $redirect_url ) {

In 4.4.2, it read:

} elseif ( is_page() && !is_feed() && isset($wp_query->queried_object) && 'page' == get_option('show_on_front') && $wp_query->queried_object->ID == get_option('page_on_front') && ! $redirect_url ) {

It appears that the change from '$wp_query->queried_object->ID' to 'get_queried_object_id()' causes the change in behavior, which is strange considering that function is supposed to do the same thing.

I hope this additional information is useful.

#6 @michael.bucklin
20 months ago

Okay, so i think what is happening is that Wordpress is trying to make sure the front page is always redirected to "/". For example, if i had a page with the slug 'home', and i then set that page as the front page, i would want mysite.com/home/ to redirect to just mysite.com. The problem is that this redirect now appears to happen even if /home/ is not on the URL. This redirect is what is causing the URL parameters to change, as PHP sees all periods as underscores and can't re-add them in the original form.

I think if this check was fixed so that the redirect only happens if /pageslug/ was in the URL, then this issue would go away.

#7 @michael.bucklin
20 months ago

I think i narrowed it down even further. The following was removed from line 175:

isset($wp_query->queried_object)

This causes the front page to redirect to "/" even if you are already there. If we add back in this code, this bug is fixed.

#8 @threeatetwo
20 months ago

@swissspidy I'm able to reproduce this. Will there be a fix in the next release?

#9 @swissspidy
19 months ago

@michael.bucklin Thanks for the details! I think you explained well enough, I've just digressed while investigating the cause.

This redirect is what is causing the URL parameters to change, as PHP sees all periods as underscores and can't re-add them in the original form.

There were some changes to canonical redirects, see #21602, #35344, #35847 for example.

I don't think the redirect is not the problem here. It only brings the issue with the replaced periods to light, which apparently is being done by WordPress at some point, not PHP itself. At least that's what I saw when I had a second look.

For the buggy redirect, I recommend you to report it in one of the tickets I mentioned.

Note: See TracTickets for help on using tickets.