Problem/Motivation

On PHP7.4 server + Drupal 9.2.6

php --version
PHP 7.4.23 (cli) (built: Aug 26 2021 15:51:55) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.23, Copyright (c), by Zend Technologies
    with Xdebug v3.0.4, Copyright (c) 2002-2021, by Derick Rethans

Steps to reproduce

Having Error messages to display as "All messages, with backtrace information"
When I navigate to "/admin/modules/browse"
Then I get the following notice

Notice: Array to string conversion in Drupal\project_browser\DrupalOrg\DrupalOrgProject->setBody() (line 182 of modules/contrib/project_browser/src/DrupalOrg/DrupalOrgProject.php).
Drupal\project_browser\DrupalOrg\DrupalOrgProject->setBody(Array) (Line: 118)
Drupal\project_browser\DrupalOrg\DrupalOrgProject->__construct(Array) (Line: 23)
Drupal\project_browser\DrupalOrg\DrupalOrgProjects->Drupal\project_browser\DrupalOrg\{closure}(Array)
array_map(Object, Array) (Line: 22)
Drupal\project_browser\DrupalOrg\DrupalOrgProjects->__construct(Array) (Line: 90)
Drupal\project_browser\Controller\DrupalOrgProxyController->getAllProjects(Object)
call_user_func_array(Array, Array) (Line: 123)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 578)
Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 124)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array) (Line: 97)
Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}() (Line: 158)
Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 80)
Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 57)
Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 106)
Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 47)
Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 52)
Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 23)
Stack\StackedHttpKernel->handle(Object, 1, 1) (Line: 716)
Drupal\Core\DrupalKernel->handle(Object) (Line: 19)

Proposed resolution

  • Not sure if we should keep using strip_tags. If we could use use Drupal\Component\Utility\Html; and Html::escape
  • Use is_array, is_countable to check or any equivalent check functions before passing. Or a (string) casing option

Remaining tasks

  • ✅ File an issue about this project
  • ✅ Check on arrays before passing or casting with PHP7.4 or change from using strip_tags
  • ✅ Testing to ensure no regression
  • ✅ Code review from core team member
  • ✅ Full testing and approval
  • ❌ Credit contributors

User interface changes

  • None

API changes

  • None

Data model changes

  • None
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

RajabNatshah created an issue. See original summary.

Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

I have noticed that when I do php --version

rajab@vardot-dev:/var/www/html/dev/drupal9c1project_browser/web/modules/contrib$ php --version
PHP 7.4.23 (cli) (built: Aug 26 2021 15:51:55) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.23, Copyright (c), by Zend Technologies
    with Xdebug v3.0.4, Copyright (c) 2002-2021, by Derick Rethans

But when I go to "/admin/reports/status/" with a Drupal 9.2.6 I get

PHP
Version
7.3.30-1+ubuntu21.04.1+deb.sury.org+1 (more information)
It is recommended to upgrade to PHP version 7.4 or higher for the best ongoing support. See PHP's version support documentation and the Drupal 8 PHP requirements handbook page for more information.

Still an issue with public $body = [];
And strip_tags($this->body['summary'], ['p', 'a', 'b', 'i', 'u', 'em', 'strong'])

If changed the body to array
and strip_tags($this->body['summary'], '<p><a><b><i><u><em><strong>')

But at this link
https://www.php.net/manual/en/function.strip-tags.php
it says

$text = '<p>Test paragraph.</p><!-- Comment --> <a href="#fragment">Other text</a>';
echo strip_tags($text);
echo "\n";

// Allow <p> and <a>
echo strip_tags($text, '<p><a>');

// as of PHP 7.4.0 the line above can be written as:
// echo strip_tags($text, ['p', 'a']);

as of PHP 7.4.0 the line above can be written as:

strip_tags($text, ['p', 'a']);

Rajab Natshah’s picture

We have to be careful as some body and summaries may have a wrong HTML formatting or some have

<?php 
 ?> 

and inline links with parameters

Note, strip_tags will remove anything looking like a tag - not just tags - i.e. if you have tags in attributes then they may be removed too,

e.g.

    $test='<div a="abc <b>def</b> hij" b="1">x<b>y</b>z</div>';
    $echo strip_tags($test, "<div><b>");

will result in

   <div a="abc bdef/b hij" b="1">x<b>y</b>z</div>Note, strip_tags will remove anything looking like a tag - not just tags - i.e. if you have tags in attributes then they may be removed too,

e.g.

    <?php
    $test='<div a="abc <b>def</b> hij" b="1">x<b>y</b>z</div>';
    $echo strip_tags($test, "<div><b>");

will result in

   <div a="abc bdef/b hij" b="1">x<b>y</b>z</div>

   
Rajab Natshah’s picture

Having a patch for PHP7.4
and another for PHP7.3

I like to keep the new way with array for PHP7.4
Maybe it's faster

Not sure if we should keep using strip_tags
as it's not the smartest tag striping way. in case of mixed wrong HTML or some other save filtered data or links

Rajab Natshah’s picture

Issue summary: View changes
Status: Active » Needs review
Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Better patch for PHP7.4

Rajab Natshah’s picture

Issue summary: View changes
Rajab Natshah’s picture

Issue summary: View changes

Not sure if we should keep using strip_tags.
If we could use use Drupal\Component\Utility\Html;
and Html::escape

rlnorthcutt’s picture

1) As noted in the PHP docs, strip_tags() can actually still pass potential malicious attributes (onload, onmouseover, etc). Of course, we should hope and expect that the input filter on D.O side would handle that (though I am not sure).

2) Using other utilities or functions on the Drupal side to clean up the results will work, BUT it carries a hit on the processing required. It is a small hit, to be sure, but worth considering. Ideally, we want this to be a lean as possible.

3) Do we need the formatting? We are pulling in the summary and trimming it, so why not just remove all formatting? That would have the added benefit of keeping all summaries more uniform.

4) Ideally, this work is done on the D.O side. So, we should actually be able to just retrieve the "summary" of the body field. I'm not sure if the current D7 API gives us this option, but we should be able to do this in the D9 version. If possible, pushing this up to the API level would be ideal.

My suggestion is to use strip_tags without any parameters so it just removes all tags. That is clean, and secure. We can open another issue to look at the ideal way to get the summary from the D9 API.

Rajab Natshah’s picture

Agrees on using strip_tags for sure.
Searched on how they do strip_tags in Drupal core.
They are using Html::escape(strip_tags($perm_item['title'])).


Or Unicode::truncate(Html::escape(trim(strip_tags((string) $this->body['summary'])))) .. :) big one!
So many things to fix .. the truncate for languages, the escape, trimming, striping tags
Some are using Html::decodeEntities

As Ron said: this should come readily from the new JSON:API endpoint.
Too much to do in local sites for each project. It should have things ready for the Project Browser. Only to play with the UI and render the data.
No extra local pre-processing for data.

My onion on this if we could have a field. which could be named "project_browser_summary" or "plain_text_summary" in projects. Filtering and editing for that will be in the Drupal.org project edit page. and JSON:API could manage extra filtering.

If a custom Project Browser plugin is doing more pre-processing. It will be for a specially fixed filtering case or ready yml or custom JSON:API endpoint.

Rajab Natshah’s picture

Title: Notice: Array to string conversion » Fix Notice: Array to string conversion
FileSize
1.01 KB

Follow up on feedback from #14

rlnorthcutt’s picture

Code looks good. Just need someone to test it, but I think it should work well!

gaurav.kapoor’s picture

Status: Needs review » Reviewed & tested by the community

Here are my thoughts on this issue,

1. The patch applies and cleanly with the latest release.
2. This change is nice as $body is accessed as an array in the entire file.

-    public $body;
+    public $body = [];

3. Because of this change, I noticed links and bold text got removed from the description of few modules. If we are ok with removing all tags for now (as mentioned in #14 as well) and look for a better alternative to get summary in future, this is an RTBC for me.

-        $this->body['summary'] = strip_tags($this->body['summary'], ['p', 'a', 'b', 'i', 'u', 'em', 'strong']);
+        $this->body['summary'] = Html::escape(strip_tags($this->body['summary']));

4. Didn't get any notice anymore on PHP 7.4 and PHP 8. Maybe notice was only in previous PHP versions.

chrisfromredfin’s picture

Issue summary: View changes

This is good as is. We do need to get testing working, but that's being worked on in a separate issue, and as this is fairly minor I've manually tested this (thanks DrupalPod!).

chrisfromredfin’s picture

Status: Reviewed & tested by the community » Fixed

Pushed to 1.0.x!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.