wp-media/search-and-replace

PHP Notice

cfoellmann opened this issue · 6 comments

On PHP 7.0.* I get the following notices:

Notice: Undefined offset: 0 in /home/wus/webapps/wus-wp/public/wp-content/plugins/search-and-replace/inc/FileDownloader.php on line 222

Notice: Undefined offset: 0 in /home/wus/webapps/wus-wp/public/wp-content/plugins/search-and-replace/inc/FileDownloader.php on line 230

Notice: Undefined offset: 0 in /home/wus/webapps/wus-wp/public/wp-content/plugins/search-and-replace/inc/FileDownloader.php on line 232

Notice: Undefined offset: 0 in /home/wus/webapps/wus-wp/public/wp-content/plugins/search-and-replace/inc/FileDownloader.php on line 236

These notices are repeated multiple times in a single request.
maybe worth investigating

What you doing, if you get this notices? I haven't seen this before in different tests.

Additional feedback https://wordpress.org/support/topic/notic-undefined-offset-reported-in-search-replace-details/

When running Search and Replace v3.1.2 I am getting PHP Notice errors in the ‘View details’ just for changes in the wp_postmeta table. A sample message is:

( ! ) Notice: Undefined offset: 0 in /var/www/wphba/wp-content/plugins/search-and-replace/inc/FileDownloader.php on line 222
Call Stack

Time Memory Function Location

1 0.0002 281840 {main}( ) ../tools.php:0
2 0.0002 283136 require_once( ‘/var/www/wphba/wp-admin/admin.php’ ) ../tools.php:10
3 2.1471 5794072 do_action( ) ../admin.php:222
4 2.1472 5794776 WP_Hook->do_action( ) ../plugin.php:453
5 2.1472 5794872 WP_Hook->apply_filters( ) ../class-wp-hook.php:323
6 2.1474 5796072 call_user_func_array ( ) ../class-wp-hook.php:298
7 2.1474 5796584 Inpsyde\SearchReplace\Page\Manager->render( ) ../class-wp-hook.php:298
8 2.1603 5797640 Inpsyde\SearchReplace\Page\Manager->save( ) ../Manager.php:120
9 2.1650 5798368 Inpsyde\SearchReplace\Page\SearchReplace->save( ) ../Manager.php:50
10 2.1679 5799216 Inpsyde\SearchReplace\Page\SearchReplace->run_replace( ) ../SearchReplace.php:152
11 12.1238 5992624 Inpsyde\SearchReplace\FileDownloader->show_changes( ) ../SearchReplace.php:205
12 12.1450 6000968 Inpsyde\SearchReplace\FileDownloader->trim_search_results( ) ../FileDownloader.php:172

There are 6 similar notices for each row and in place of the usual formatted output it displays:

Old value: …… New value: …… row 7 column meta_value

widoz commented

@cfoellmann Just to give some context about the issue:

The issue is with trying to accessing to $trimmed_results[ 0 ][ $i ], that code is used t build the string for old_value and new_value up to max 50 characters. Those value wel be used within th report table.

I suppose that issue is with the inner array in $trimmed_results since the for construct doens't get executed if $i < $imax where $imax = count( $trimmed_results ) = 0.

Need further investigation because if there are no changes to show, the method trim_search_results isn't called, but if there are elements founds the $trimmed_results should have at least one element in the second level.

I'm not able to replicate the issue with php 7.1 I don't think may be an issue related specifically to php7.0 but I'll setup the env with this version just to perform some test.

May we have some more info about $haystack and $needle?
$haystack = The full string to search in.
$needle = The string/char to search for.

widoz commented

I think I found the problem.

I was convinced by the context that the function call preg_match_all( '@.{0,50}' . $needle . '.{0,50}@', $haystack, $trimmed_results ); had to result always in a valid multidimensional array.

Btw, if for some reason the call to preg_match_all return 0 the issue come out.

Despite the context I think it's correct to check for the valid matches value.

This should prevent to try to access to an index that doesn't exists.
Indeed, the value for $trimmed_results is always an array, an array with one element ad index 0 but it's always an array. A false is returned only when an error occur.

So when we start the loop:

$imax = count( $trimmed_results );
for ( $i = 0; $i < $imax; $i ++ ) {
   // ...logic
}

The value for the $imax is 1.
So, instead of get the number of matched values by counting the $trimmed_results variable, I suggest to use the value returned by preg_match_all.

Also, skipping to print the rows where function trim_search_results return the empty string.

After this merge the problem should be fixed. @cfoellmann maybe you can try and give us feedback?

This is old. Sorry for not responding. It is resolved