Opened 8 months ago
Last modified 3 months ago
#63066 new defect (bug)
Warning when array passed to wp_check_invalid_utf8()
| Reported by: |
|
Owned by: | |
|---|---|---|---|
| Milestone: | Awaiting Review | Priority: | normal |
| Severity: | normal | Version: | 6.7.2 |
| Component: | General | Keywords: | |
| Focuses: | Cc: |
Description
wp_check_invalid_utf8() specifies
* @param string $text The text which is to be checked.
and will trigger the following warning if passed an array.
PHP Warning: Array to string conversion in /var/www/html/wp-includes/formatting.php on line 1096
To reproduce
curl -v "http://localhost/wp-login.php?redirect_to[]=http://"
I would suggest returning an empty string if presented with an array.
Attachments (1)
Change History (22)
#2
@
3 months ago
@garrigan I would be reluctant to add random type checks to this function whose documentation already indicates that $text ought to be a string. if anything, if we want to perform the runtime type-checking we would want to ask for what we want rather than what we don’t want, e.g. if ( ! is_string( $text ) ) { return ''; }
it appears, however, that the problem is likely higher up in the call stack; something is calling wp_check_invalid_utf8() improperly. are you able to to log what this is?
if you are able to recreate the error condition then you can temporarily modify the WordPress file to get out the data and call stack.
<?php function wp_check_invalid_utf8( $text, $strip = false ) { if ( is_array( $text ) ) { var_dump( $text ); throw new Error( 'should only be passing string; not array to wp_check_invalid_utf8()' ); } $text = (string) $text; …
#3
@
3 months ago
Hi Dennis,
WordPress, PHP ... is not within my area of expertise thus I need to clarify your request so that I am on the same page as you.
Do you want me to add that block of code to the file, wp-includes/formatting.php, repeat the issue that caused the 404 error, and report back the results?
Where will I see the results please?
Jim
#4
@
3 months ago
I made the change to the file. I have an image, but I do not know how to attach it thus I will upload the image to my production site, and I will provide a link to it.
I am reverting to a snapshot of a test environment that has less plugins.
#5
@
3 months ago
Hi Dennis, I am not seeing any output. I also added an echo statement and I do not see anything.
I will upload the screen images to my production environment so you can see a portion of the steps.
I know the issue occurred because I see the 404 in the log files.
#6
@
3 months ago
Hi Dennis,
I verified the following links before sending this message.
modified file: https://www.garrigan.nyc/images/formatting-php-with-test-change-one.png
The customizer opens properly.: https://www.garrigan.nyc/images/formatting-php-with-test-change-two.png
The customizer fails to open initially after modifying the file.: https://www.garrigan.nyc/images/formatting-php-with-test-change-three.png
404 message - evidence the issue occurs: https://www.garrigan.nyc/images/syslog-01.png
Jim
#7
@
3 months ago
It seems like there are three different issues here.
1. The original reported issue on the wp-login.php page.
The underlying cause of the problem appears to be that login_footer() in wp-login.php does not check that $_GET['redirect_to'] is a string before passing it to sanitize_url().
In [58023], validation of redirect_to was added in a few different locations, but it looks like this one was missed.
2. The "Array to string conversion" issue on the wp-admin/customize.php page.
I suspect this is coming from a plugin or theme (I can't reproduce it on a clean install with no plugins), but a stack trace will probably be needed to know for sure.
@garrigan - did you check your site's error log? I think there should be a stack trace there?
3. The 404 error
This is a known issue: #54435
I don't think this is related to the "Array to string conversion" issue.
#8
follow-up:
↓ 9
@
3 months ago
Hi,
WordPress and PHP are not my areas of expertise. My world was on-premises Windows Server / Exchange.
What do you mean by "site's error log" , please?
I have the NGINX server logs and I do have debug logging enabled in wp-config.php.
I will check messages again during the morning. I am in NYC.
#9
in reply to:
↑ 8
@
3 months ago
Replying to garrigan:
What do you mean by "site's error log" , please?
In this comment (from February) you posted what looks like your site's error log:
https://wordpress.org/support/topic/post-wp-admin-admin-ajax-php-http-2-0-404/#post-18321626
Feb 20 11:14:46 vm_hostname 2/20/2025 11:14:46 [error] 8523#8523: *70 FastCGI sent in stderr: PHP message: PHP Warning: Array to string conversion in /data-path/wp-includes/formatting.php on line 1096 while reading upstream, client: 2001:XXX:XXX:0:XXX:XXX:XXXX:XXXX, server: staging.mydomain.com, request: GET /wp-admin/customize.php HTTP/2.0, upstream: fastcgi://unix:/run/php-fpm/www.sock:, host: staging.mydomain.com, referrer: https://staging.mydomain.com/wp-admin/admin.php?page=neve-welcome
Can you check that log again and see if there are any messages from today? I think there should be a stack trace in there.
#10
@
3 months ago
more plugins Aug 11 18:05:46 staging 8/11/2025 18:05:46 [error] 3166#3166: *208 FastCGI sent in stderr: PHP message: PHP Fatal error: Uncaught Error: should only be passing string; not array to wp_check_invalid_utf8() in /my-path/wp-includes/formatting.php:1100 Aug 11 18:07:04 staging 8/11/2025 18:07:03 [error] 3169#3169: *568 FastCGI sent in stderr: PHP message: PHP Fatal error: Uncaught Error: should only be passing string; not array to wp_check_invalid_utf8() in /my-path/wp-includes/formatting.php:1100 Aug 11 18:07:04 staging 8/11/2025 18:07:03 [error] 3169#3169: *568 FastCGI sent in stderr: ntrol.php(477): esc_attr(Array) Aug 11 18:07:18 staging 8/11/2025 18:07:17 [error] 3169#3169: *568 FastCGI sent in stderr: PHP message: PHP Fatal error: Uncaught Error: should only be passing string; not array to wp_check_invalid_utf8() in /my-path/wp-includes/formatting.php:1100 Aug 11 18:08:56 staging 8/11/2025 18:08:55 [error] 3166#3166: *1182 FastCGI sent in stderr: PHP message: PHP Warning: Array to string conversion in /my-path/wp-includes/formatting.php on line 1096 while reading upstream, client: 2001:, server: ~^(.+)(\.)((james|jim)?garrigan.*)$, request: GET /hidden-admin/customize.php HTTP/3.0, upstream: fastcgi://unix:/run/my-path/www.sock:, referrer: https://staging.my-domain.com/hidden-admin/ Aug 11 18:20:01 staging 8/11/2025 18:20:01 [error] 3167#3167: *2235 FastCGI sent in stderr: PHP message: PHP Warning: Array to string conversion in /my-path/wp-includes/formatting.php on line 1096 while reading upstream, client: 2001:, server: ~^(.+)(\.)((james|jim)?garrigan.*)$, request: GET /hidden-admin/customize.php HTTP/2.0, upstream: fastcgi://unix:/run/my-path/www.sock:, host: staging.my-domain.com, referrer: https://staging.my-domain.com/hidden-admin/ Aug 11 18:22:42 staging 8/11/2025 18:22:41 [error] 3167#3167: *2235 FastCGI sent in stderr: PHP message: PHP Warning: Array to string conversion in /my-path/wp-includes/formatting.php on line 1096 while reading upstream, client: 2001:, server: ~^(.+)(\.)((james|jim)?garrigan.*)$, request: GET /hidden-admin/customize.php HTTP/2.0, upstream: fastcgi://unix:/run/my-path/www.sock:, host: staging.my-domain.com, referrer: https://staging.my-domain.com/hidden-admin/ less plugins Aug 11 18:44:23 staging 8/11/2025 18:44:23 [error] 2834#2834: *344 FastCGI sent in stderr: PHP message: PHP Fatal error: Uncaught Error: should only be passing string; not array to wp_check_invalid_utf8() in /my-path/wp-includes/formatting.php:1098 Aug 11 18:44:58 staging 8/11/2025 18:44:58 [error] 2835#2835: *729 FastCGI sent in stderr: PHP message: PHP Fatal error: Uncaught Error: should only be passing string; not array to wp_check_invalid_utf8() in /my-path/wp-includes/formatting.php:1098 Aug 11 18:45:17 staging 8/11/2025 18:45:16 [error] 2835#2835: *778 FastCGI sent in stderr: PHP message: PHP Fatal error: Uncaught Error: should only be passing string; not array to wp_check_invalid_utf8() in /my-path/wp-includes/formatting.php:1098 Aug 11 18:46:50 staging 8/11/2025 18:46:50 [error] 2835#2835: *833 FastCGI sent in stderr: PHP message: PHP Warning: Array to string conversion in /my-path/wp-includes/formatting.php on line 1096 while reading upstream, client: 10., server: ~^(.+)(\.)((james|jim)?garrigan.*)$, request: GET /wp-admin/customize.php HTTP/3.0, upstream: fastcgi://unix:/run/my-path/www.sock:, referrer: https://staging.my-domain.com/wp-admin/ Aug 11 18:54:34 staging 8/11/2025 18:54:33 [error] 2834#2834: *1222 FastCGI sent in stderr: PHP message: PHP Warning: Array to string conversion in /my-path/wp-includes/formatting.php on line 1096 while reading upstream, client: 10., server: ~^(.+)(\.)((james|jim)?garrigan.*)$, request: GET /wp-admin/customize.php HTTP/3.0, upstream: fastcgi://unix:/run/my-path/www.sock:, referrer: https://staging.my-domain.com/wp-admin/ Aug 11 18:56:37 staging 8/11/2025 18:56:37 [error] 2837#2837: *1326 FastCGI sent in stderr: PHP message: PHP Warning: Array to string conversion in /my-path/wp-includes/formatting.php on line 1096 while reading upstream, client: 10., server: ~^(.+)(\.)((james|jim)?garrigan.*)$, request: GET /wp-admin/customize.php HTTP/3.0, upstream: fastcgi://unix:/run/my-path/www.sock:, referrer: https://staging.my-domain.com/wp-admin/
#11
@
3 months ago
@garrigan, can you try this?
<?php function wp_check_invalid_utf8( $text, $strip = false ) { if ( is_array( $text ) ) { error_log( 'should only be passing string; not array to wp_check_invalid_utf8()' ); ob_start(); debug_print_backtrace(); error_log( ob_get_clean() ); } $text = (string) $text; ...
Modify your wp-includes/formatting.php file to include the above code, then visit the customizer again, and check your error log file.
#13
follow-up:
↓ 19
@
3 months ago
Aug 12 12:42:40 staging 8/12/2025 12:42:40 [error] 3046#3046: *358 FastCGI sent in stderr: PHP message: should only be passing string; not array to wp_check_invalid_utf8(); PHP message: #0 /my-path/www/wp-includes/ while reading upstream, client: 2001:, server: ~^(.+)(\.)((james|jim)?garrigan.*)$, request: GET /wp-admin/customize.php HTTP/3.0, upstream: fastcgi://unix:/run/my-path/www.sock:, referrer: https://staging.my-domain.com/wp-admin/ Aug 12 12:42:40 staging 8/12/2025 12:42:40 [error] 3046#3046: *358 FastCGI sent in stderr: formatting.php(4702): wp_check_invalid_utf8(Array)
#14
@
3 months ago
I will create a dedicated snapshot for my contributions to this ticket.
I will use the latest version of WordPress.
I will import the theme twentytwentyone.2.6.zip.
I will not install plugins.
I confirmed this theme uses the customizer and consequently it generates the same issue.
I will use an FQDN that is different from production.
If you want to access it, then you will be able to do so.
#15
@
3 months ago
With the new, minimalist test environment, I do not see errors, but I do see the same 404 message upon exiting from the customizer.
Aug 12 16:13:02 staging nginx: 10.x.y.z - - [12/Aug/2025:16:13:01 -0400] "POST /wp-admin/admin-ajax.php HTTP/2.0" 404 47 "https://dev1a.my-domain.com/wp-admin/customize.php?return=%2Fwp-admin%2F" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:141.0) Gecko/20100101 Firefox/141.0" "-" dev1a.my-domain.com "POST https://dev1a.my-domain.com" "DNT -" _MobileDevice-No_ _botnotdetected_ "expires " "MyHardenList " "ssl_early_data -" "early_hints "
#16
@
3 months ago
Hm. It does sound like this could be a problem introduced by some plugin if it doesn’t happen on your minimalist test environment, though that doesn’t necessarily have to be the case.
Given that @siliconforks mentioned the existing issue for the 404 page, this may be hard to figure out unless we can identify specifically what triggers the issue.
If you can find a specific plugin causing the array-to-string error to appear, you might reach out to that plugin for support on their side to fix the issue. While I definitely want us to figure this out, I do want to reiterate that I think adding type checks at runtime for situations that aren’t supposed to occur (and which in this case are well-documented) is something that would be good to avoid; there is no end to that direction of code unfortunately.
#17
@
3 months ago
Hi Dennis.
In the minimalist test environment, I do not have any active plugins.
I am fine with providing access to the minimalist test environment.
It is a VM within VMware Workstation.
Regarding other plugins within the more robust test environments, as you are probably aware, if I go down that rabbit hole, I may never be seen or heard from again.
The other test environments use the same FQDN's as production thus I would need to create a "jump" server.
Jim
#18
@
3 months ago
With the new, minimalist test environment, I do not see errors
Sorry @garrigan if I misunderstood, but I thought this was saying that the array-to-string conversion didn’t happen in the test environment.
Regarding other plugins within the more robust test environments, as you are probably aware, if I go down that rabbit hole, I may never be seen or heard from again.
If the problem turns out to be caused by those plugins, unfortunately we’ll not be able to do anything here, as this is the place to collaborate on working on WordPress itself. I had originally moved this conversation back to the forums where you originally posted, because that is the appropriate place to try and get help from others diagnosing issues with your particular installation.
Perhaps. @leedxw has some more context to share to reproduce the issue in Core.
If the issue is that you don’t see the errors, it may be helpful to extend the severity of the patch you applied before to shut down the PHP process and display everything right on the page.
#19
in reply to:
↑ 13
@
3 months ago
Replying to garrigan:
Aug 12 12:42:40 staging 8/12/2025 12:42:40 [error] 3046#3046: *358 FastCGI sent in stderr: PHP message: should only be passing string; not array to wp_check_invalid_utf8(); PHP message: #0 /my-path/www/wp-includes/ while reading upstream, client: 2001:, server: ~^(.+)(\.)((james|jim)?garrigan.*)$, request: GET /wp-admin/customize.php HTTP/3.0, upstream: fastcgi://unix:/run/my-path/www.sock:, referrer: https://staging.my-domain.com/wp-admin/ Aug 12 12:42:40 staging 8/12/2025 12:42:40 [error] 3046#3046: *358 FastCGI sent in stderr: formatting.php(4702): wp_check_invalid_utf8(Array)
It looks like the stack trace is getting cut off for some reason...
Maybe try this instead:
Edit your wp-config.php file and find the WP_DEBUG line and change it to this:
define( 'WP_DEBUG', true );
Also add the following line:
define( 'WP_DEBUG_LOG', true );
Then visit the customizer again. This should have the effect of creating a file named wp-content/debug.log containing the information needed to find the cause of the issue (it may show that a plugin is triggering this).
Note: this configuration is not really recommended for production environments so I recommend changing it back as soon as you are done (i.e., set WP_DEBUG back to false and remove the WP_DEBUG_LOG line).
#21
@
3 months ago
Working with opensource products and chasing down issues always reminds me of the following:
The phrase "Never get out of the boat" ... from the movie Apocalypse Now. It's a line spoken by the character Chef, ... it becomes a mantra for avoiding unnecessary risks and staying focused on the mission ... *Copied from a google search.
Modify wp_check_invalid_utf8() to return an empty string if passed an array