String not trimmed generates 500 internal server error in /search/authors context

Hello, I am writing this to describe a possible bug that I found and to have some help to hit the right spot in the changes to solve this possible bug. I am using ojs version 3.3.0.13.

When I try to access the context /search/authors page in a journal I get a 500 internal server error and the log shows the following stack trace:

PHP Fatal error: Uncaught InvalidArgumentException: Passed value cannot be an array in /var/www/html/ojs/lib/pkp/lib/vendor/danielstjules/stringy/src/Stringy.php:45\nStack trace:\n#0 /var/www/html/ojs/lib/pkp/lib/vendor/danielstjules/stringy/src/Stringy.php(73): Stringy\\Stringy->__construct(Array, NULL)\n#1 /var/www/html/ojs/lib/pkp/classes/core/PKPString.inc.php(164): Stringy\\Stringy::create(Array)\n#2 /var/www/html/ojs/cache/t_compile/34a9c59b4a19f42bae23f8270f7d53d621182573^c2055d14f27582f3361894f4184ce1a4c0497385_0.app.frontendpagessearchAuthor.php(58): PKPString::substr(Array, 0, 1)\n#3 /var/www/html/ojs/lib/pkp/lib/vendor/smarty/smarty/libs/sysplugins/smarty_template_resource_base.php(123): content_641352170cbf36_90450511(Object(Smarty_Internal_Template))\n#4 /var/www/html/ojs/lib/pkp/lib/vendor/smarty/smarty/libs/sysplugins/smarty_template_compiled.php(114): Smarty_Template_Resource_Base->getRenderedTemplateCode(Object(Smarty_Internal_Template))\n#5 /var/www/html/ojs/lib/pkp/lib/vendor/smarty/smarty/libs/sysplugins/smarty_int in /var/www/html/ojs/lib/pkp/lib/vendor/danielstjules/stringy/src/Stringy.php on line 45, referer: https://my-website/ojs/index.php/my-journal

After some digging I found that values in the table author_settings in the ‘familyName’ attribute, where the column setting_value has a value not trimmed (for example ’ Baptista ', 'Baptista ’ or ‘ Baptista ‘) it results in the 500 error.

for debug purpose I add a line in the ojs/lib/pkp/classes/core/PKPString.inc.php to identify the value that is generating the error:

        static function substr($string, $start, $length = null) {
                error_log(print_r($string, true));
                return (string) Stringy\Stringy::create($string)->substr($start, $length);
        }

the result of the debug:

Array\n(\n [en_US] => Almeida\n)\n,

other value:
Array\n(\n [en_US] => Chebenova \n [es_ES] => \n [pt_BR] => \n)\n

In this example the author has familyName empty for the locales pt_BR and es_ES, but if I delete the familyName of these locales I am still facing the error because the familyName in the locale en_US looks like ‘ Chebenova’. If I remove the the space before the familyName the error stops (for this author of course :P)

So, I think that if the value has backspaces before or after the value, the value is treated like an array and the function does not accept arrays to create substring.

If I add a trim in the return of the function substr like:
return (string) Stringy\Stringy::create(trim($string))->substr($start, $length);
in the file ojs/lib/pkp/classes/core/PKPString.inc.php the page start working again, but this function is globally used in ojs and I think this may not be a good idea to trim in this function

Other problem is when the familyName is not trimmed and has space before the name, it takes the name with backspace for the top of the alphabetical list.

Another problem is, when the value in the table author_settings is not trimmed (not only in the familyName attribute) the url to view details about the author is not formed right, the search is not successful and fallback to advanced search.

Other two ways that I found to trim this strings and I think is a better way to do this is:

in the file ojs/lib/pkp/classes/submission/PKPAuthor.inc.php line 74 in the function getLocalizedFamilyName trim the return of the function:
from:
return $this->getFamilyName($this->getSubmissionLocale());
to:
return trim($this->getFamilyName($this->getSubmissionLocale()));

or directly in the smarty file ojs/templates/frontend/pages/searchAuthorIndex.tpl in the assing of the var firstLetter line 21
from:
{assign var=firstLetter value=$author->getLocalizedFamilyName()|String_substr:0:1}

to:
{assign var=firstLetter value=$author->getLocalizedFamilyName()|trim|String_substr:0:1}

Is possible to trim the input before it be insert in the database ?

Regards

Hi @igor.baptista,

The feature in which you’re encountering the problem (the author index) has been removed in more recent releases of OJS 3.3.0-x, so I’d caution against relying on it.

For details, see this GitHub issue:

Regards,
Alec Smecher
Public Knowledge Project Team

1 Like

Acknowledging that this specific page is going away, note that the stack trace and error_log() indicates that a localized array is being passed into the PKPString:substr() call. That is, the root cause seems to be not about the data containing untrimmed spaces, but rather that the search/author page is somehow passing all locale content for the family name, even though we are requesting a single localized version.

There still might be a logic error in getLocalizedFamilyName() that I’m not seeing.

1 Like