Yoast / wordpress-seo

Yoast SEO for WordPress
https://yoast.com/wordpress/plugins/seo/
Other
1.77k stars 893 forks source link

Error in workouts-integration.php affected admin on php 8 or later #17961

Open ArrayIterator opened 2 years ago

ArrayIterator commented 2 years ago

Please give us a description of what happened.

Uncaught TypeError: count(): Argument #1 ($value) must be of type Countable|array, null given in [ROOT]/wp-content/plugins/wordpress-seo/src/integrations/admin/workouts-integration.php:486 Stack trace: #0 [ROOT]/wp-content/plugins/wordpress-seo/src/integrations/admin/workouts-integration.php(486): 

https://github.com/Yoast/wordpress-seo/blob/1118789719c3748d0b8b15bff925c4d515563d4b/src/integrations/admin/workouts-integration.php#L486

$workouts_option = $this->options_helper->get( 'workouts_data', [] );
return count( $workouts_option['configuration']['finishedSteps'] ) === 5;

This maybe cause no validation has been made on count method. when $workouts_option is empty array or does not contain key (not is array) on configuration or finishedSteps it will thrown an error, cause php 8 or later is strictest than earlier.

Please describe what you expected to happen and why.

After update on latest version, admin area (dashboard) suddenly showing that wordpress has error. I also used plugins directory as symlink of subdomain.

How can we reproduce this behavior?

  1. (Probably) Update Yoast Plugin that make workouts_data[configuration][finishedSteps ] has been changed.
  2. Try to emptying / change options_helper of workouts_data that does not contains key finishedSteps

Technical info

Used versions

IMAGE

after plugin update (suddenly checked that options workouts_data[configuration] has empty)

image

Djennez commented 2 years ago

I can see it happening, but I think this is a rare case. Looking at the code, that count should always return something, even if the data does not exist in the database. That option is set to a default empty array, so it should always return 0 if no data is in the database.

Since the options framework is using caching, it might be that the value did not exist before the update and therefore a cached options array was used without that value. But that would mean that you updated from a version prior to 17.7 to 17.9, since this code was introduced in 17.7, and your caching is more robust. Could that be the case?

ArrayIterator commented 2 years ago

yep .. even on minor case and the admin dashbord thrown error, the user on admin can not resolve the issues untill deactivate plugins manually via server or fixing the code.

jameelmoses commented 2 years ago

Just experienced this same issue and had to downgrade to PHP 7.4

OneMohrTime commented 2 years ago

I just had this happen, had to rollback to 7.4 as well.

Edit: Unsure if this is helpful, but, I was able to roll SEO back to 17.6, then upgrade PHP to 8.0 without any issue.