Opened 4 months ago
Closed 4 months ago
#64870 closed defect (bug) (fixed)
Fatal TypeError: urldecode() expects string, array given in formatting.php (PHP 8+)
| Reported by: | patricedefago | Owned by: | SergeyBiryukov |
|---|---|---|---|
| Priority: | normal | Milestone: | 7.0 |
| Component: | Formatting | Version: | 6.9.1 |
| Severity: | normal | Keywords: | has-patch php8 has-unit-tests |
| Cc: | Focuses: |
Description
Description
When visiting a URL with array-style GET parameters (e.g., /?product_cat[]=clothing), WordPress core throws a fatal TypeError in wp-includes/formatting.php because urldecode() receives an array instead of a string. This occurs on PHP 8+, which enforces strict type checking for built-in functions.
Steps to reproduce
- Use WordPress 6.9.1 with PHP 8.x
- Visit a URL with an array-style query parameter, e.g.:
https://example.com/?product_cat[]=clothing - A fatal error is triggered in
wp-includes/formatting.php
Expected behavior
The page should load normally. Array GET parameters should be handled gracefully (ignored, sanitized, or skipped).
Actual behavior
Fatal error: TypeError: urldecode(): Argument #1 ($string) must be of type string, array given
Environment
- WordPress: 6.9.1
- PHP: 8.x
- Any theme/plugin combination
Analysis
The urldecode() call does not check whether the $_GET value is an array before processing. Since urldecode() only accepts strings, passing an array (which PHP creates automatically from query strings like param[]=value) causes a fatal TypeError on PHP 8+. On PHP 7.x, this was silently converted, but PHP 8 enforces strict types on internal functions.
A type check (e.g., is_array() or ! is_string()) before calling urldecode() would prevent the crash.
Related
- WooCommerce issue with the same root cause: https://github.com/woocommerce/woocommerce/issues/63582
- The WooCommerce-specific instance in
wc-product-functions.phpis being fixed separately.
Change History (4)
This ticket was mentioned in PR #11269 on WordPress/wordpress-develop by @alexodiy.
4 months ago
#1
- Keywords has-unit-tests added
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)
When a URL contains array-style GET parameters for a hierarchical taxonomy (e.g.
?product_cat[]=clothingor?category_name[]=foo),wp_basename()receives an array instead of a string. This causes a fatalTypeErroron PHP 8+ becauseurlencode()insidewp_basename()only accepts strings.## Changes
is_string()check before callingwp_basename()on the taxonomy query var value inWP_Query::parse_tax_query().is_array()check on the next line already handles array values correctly, so this change only prevents the fatal crash without altering query behavior.TypeErrorwhen a hierarchical taxonomy query var is passed as an array.Trac ticket: https://core.trac.wordpress.org/ticket/64870
Props patricedefago.
Fixes #64870.