[D7 PHP 8.1] strpos(): Passing null to parameter #1 ($haystack) of type string is deprecated in text_summary()

Created on 21 March 2022, about 2 years ago
Updated 15 June 2023, about 1 year ago

Problem/Motivation

We are experiencing multiple deprecation warnings on PHP 8.1 in the text_summary() function:

Deprecated function: strpos(): Passing null to parameter #1 ($haystack) of type string is deprecated in text_summary() (line 358 of /modules/field/modules/text/text.module).
Deprecated function: mb_strlen(): Passing null to parameter #1 ($string) of type string is deprecated in drupal_strlen() (line 482 of /includes/unicode.inc).

The first one is directly in text_summary() and the second one is in drupal_strlen() function which is called by text_summary().

The problem is not the Drupal core itself, but some modules seems to be calling text_summary() with null, which results in this warning. I can point out at Metatag module trying to generate node tokens, but it seems like this is not the only one module causing this. This will happen when there is a node with a text_with_summary field type and this field has a null value. Some modules are directly using this null value (like Metatag module) and it will end up with this deprecation warnings.

A im posting this as a Drupal core issue, because in some other issues we went the way of sanitizing it on the Drupal core side, as multiple modules can cause this. See the recent check_plain() fix: #3254699: [D7 PHP 8.1] check_plain(): Passing null to parameter #1 check_plain() includes/bootstrap.inc, line 1907 β†’

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

πŸ› Bug report
Status

Fixed

Version

7.0 ⚰️

Component
TextΒ  β†’

Last updated 9 days ago

Created by

πŸ‡ΈπŸ‡°Slovakia poker10

Live updates comments and jobs are added and updated live.
  • PHP 8.1

    The issue particularly affects sites running on PHP version 8.1.0 or later.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡ΊπŸ‡ΈUnited States gbirch

    I understand that this precise issue is fixed, but the underlying problem with drupal_strlen() can be caused by many other things. Would it not be better for drupal_strlen() to return 0 if the $text is NULL?

    I.e. add the following to drupal_strlen():

    if (is_null($text)) {
      return 0;
    }
  • πŸ‡ΈπŸ‡°Slovakia poker10

    @gbirch, there are lot of functions where your mentioned approach could be used, if we decide to go this way (drupal_strtoupper(), drupal_strtolower(), ...). But preferably we try to fix reported issues where they originated. We have made few exceptions in functions, where multiple contrib modules (and probably also core modules) were sending NULL instead of a string data. But the official policy for core is not babysit broken contrib code.

    I am not sure if there are any open issues about the drupal_strlen() PHP 8 warning somewhere (except this fixed one). If yes, we can check the issue and the root cause of the problem and decide about the fix. If not, then I am not sure about fixing something, that is not an issue now. Thanks!

  • πŸ‡ΊπŸ‡ΈUnited States gbirch

    @poker10, I don't think I agree with you about which code is "broken".

    Prior to PHP 8, you could happily pass NULL to these functions in place of empty strings. The drupal_ functions you mention do not specify that the input must be a string in the PHP doc or otherwise. If they don't, then arguably the bug/incompatibility is in the drupal_ functions themselves, which don't behave as they used to, and not in the "broken" contrib code that uses them.

    If you have been calling one of these functions in your custom/contrib code, how would you know that you must pass a string, if a) previously the functions accepted NULL values happily and b) now they don't, if the function signatures are unchanged? And from a purely practical point of view, what happens here is that the core code throws notices, and you don't immediately know what code called it without analyzing the back-trace. This is not a developer friendly result.

    Finally, the whole POINT of those functions is to provide a wrapper around different PHP implementations, character sets, etc. This would be just one more compatibility wrapper.

  • πŸ‡ΈπŸ‡°Slovakia poker10

    The documentation of the drupal_strlen() function is as follows:

    /**
    * Counts the number of characters in a UTF-8 string.
    *
    * This is less than or equal to the byte count.
    *
    * @param $text
    * The string to run the operation on.
    *
    * @return integer
    * The length of the string.
    *
    * @ingroup php_wrappers
    */

    So it specifies, that the input has to be a string (in the parameter description), but it is not enforced like in D10. So yes, you were able to pass NULL to these functions prior to PHP 8 without problems, but only because the underlaying strlen() function allowed that. Here are the reasons for this change in PHP: https://php.watch/versions/8.1/internal-func-non-nullable-null-deprecation.

    Finally, the whole POINT of those functions is to provide a wrapper around different PHP implementations, character sets, etc. This would be just one more compatibility wrapper.

    Yes, this is true. But as I have mentioned earlier, we cannot fix non-existing problems. So either there is an open issue about another problem with drupal_strlen() in PHP 8+, and we can take a look at options here, or someone need to create such issue, so that we can consider this change. We are not going to do anything else in this issue, as it is closed (fixed). Thanks!

  • πŸ‡ΈπŸ‡°Slovakia poker10

    @gbirch There is a new issue πŸ› _form_validate sends null to drupal_strlen triggering deprecation notice Needs work , which looks valid and we can discuss the potential global fix for drupal_strlen() there. Thanks.

Production build 0.69.0 2024