Problem/Motivation

The exception messages in class Drupal\file\FileRepository use sprintf to feed in a destination parameter. However, instead of the normal %s designated placeholder the string has the full word %destination and the parameter is passed as an array. This produces the exception message: Invalid stream wrapper: 1estination in Drupal\file\FileRepository->writeData()

Proposed resolution

Change
sprintf('Invalid stream wrapper: %destination', ['%destination' => $destination])
into
sprintf('Invalid stream wrapper: %s', $destination)

Remaining tasks

There are three exceptions like this in core/modules/file/src/FileRepository.php

Issue fork drupal-3328694

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jonathan1055 created an issue. See original summary.

jonathan1055’s picture

Issue summary: View changes

It also makes me wonder if these exceptions are covered by any automated test, as this would have been picked up before.

cilefen’s picture

Evidently there is no test. And I guess phpstan hasn't discovered this because it is valid syntax. The $values parameter of sprintf is coerced into the data type '%d' as a '1', in this case.

cilefen’s picture

Issue tags: +Novice
jonathan1055’s picture

Version: 9.5.x-dev » 10.1.x-dev

I did try a regex search to see if there were many of them - find %d or %s with chars following: sprintf.*\%[sd]\w and this only found the three in the file mentioned.

It needs fixing in D10.1 first as the problem is still there.

rpayanm made their first commit to this issue’s fork.

sahilgidwani’s picture

Status: Active » Needs review
jonathan1055’s picture

Issue tags: -Novice +Needs tests

Thanks for starting the MR SahilGidwani. It needs a rebase which you can probably do via the MR summary page.

I think this change should also add test coverage for these three exceptions, as clearly they are not currently tested. You can probably find and extend some existing exception tests.

xjm’s picture

Status: Needs review » Needs work

NW for the test coverage. Thanks!

xjm’s picture

I would go a step further than this: The $destination already has a string parameter typehint, so sprintf() doesn't add any value here. I would just concatenate and/or use a double-quoted string. sprintf() is only really useful for formatting numbers and the like. It's not a string sanitization function and just adds overhead for exception messages.

This also made me curious if we have other places in core where sprintf() was incorrectly treated as if it were t(). I checked:

[ayrton:drupal | Thu 11:24:15] $ grep -r "sprintf" * |  grep '=>' | grep -v "vendor" | grep -v "node_modules"

I found lots of things that should probably not use sprintf(), but nothing else broken per se.

xjm’s picture

murilohp made their first commit to this issue’s fork.

murilohp’s picture

Issue tags: -Needs tests
StatusFileSize
new1.76 KB

Hey! I was reviewing this issue and fortunately we do have tests to cover the exceptions itself but we didn't have tests to cover the messages from the exceptions, so I've just added some tests to do that, and I'm also followed @xjm suggestion, instead of using sprintf(), the code can use a double-quoted string, it makes a lot of sense.

Here's a test only patch.

murilohp’s picture

Status: Needs work » Needs review
jonathan1055’s picture

Thanks @murilohp this looks good. Yes, double-quoted string with {} is perfectly adequate. Nice idea @xjm.

1) Drupal\Tests\file\Kernel\MoveTest::testInvalidStreamWrapper
Failed asserting that exception message 'Invalid stream wrapper: 1estination' contains 'Invalid stream wrapper: foo://'

These three failures in the patch prove that the additional 3 line checks are doing what we need. Good that you found a simple place to add them.

I'm happy to have this RTBC but will wait for @xjm to also review.

smustgrave’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: +Needs Review Queue Initiative

This issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.

Change in MR 3159 looks good and points from #11 appear to be addressed
#14 shows valid test coverage

@xjm in #11 you mentioned you found lots. Should a Meta task be opened to address those?

longwave’s picture

Version: 10.1.x-dev » 9.5.x-dev
Status: Reviewed & tested by the community » Fixed

Committed and pushed 465482a571 to 10.1.x and 8caea2cf9b to 10.0.x and 37fb0a9950 to 9.5.x. Thanks!

  • longwave committed 8caea2cf on 10.0.x
    Issue #3328694 by murilohp, rpayanm, jonathan1055, xjm, cilefen:...

  • longwave committed 465482a5 on 10.1.x
    Issue #3328694 by murilohp, rpayanm, jonathan1055, xjm, cilefen:...

  • longwave committed 37fb0a99 on 9.5.x
    Issue #3328694 by murilohp, rpayanm, jonathan1055, xjm, cilefen:...

Status: Fixed » Closed (fixed)

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

jonathan1055’s picture

To follow up @xjm's work in #11 and @smustgrave's question in #17, attached is the result of grep -r "sprintf" * | grep '=>' | grep -v "vendor" | grep -v "node_modules" in 10.1.x. There are 35 lines, but some of these are not a problem because the => is before the sprintf and so the array is not part of the sprintf. Therefore it is a small problem, and could be fixed quite easily.