Skip to content

S3 adapter should always use / separator independent of the host OS #55119

Open
@stancl

Description

@stancl

Laravel Version

12.x

PHP Version

8.4

Database Driver & Version

irrelevant

Description

I got a bug report in my tenancy package, archtechx/tenancy#1333

After reproducing it and not finding any logic on our end that would cause this, I tried to reproduce this without tenancy logic involved and managed to do so.

The bug is essentially that temporaryUrl() and possibly other methods (not confirmed) use the OS-specific DIRECTORY_SEPARATOR while S3 only supports /.

From a very brief source dive the cause seems to be these prefixPath() calls:

'Key' => $this->prefixer->prefixPath($path),

Which use $this->prefixer, defined in the parent class and initialized as:

$separator = $config['directory_separator'] ?? DIRECTORY_SEPARATOR;
$this->prefixer = new PathPrefixer($config['root'] ?? '', $separator);

The only thing I'm confused by is that these calls are abundant in the S3 adapter so the issue should exist in other cases too. It might be that this bug exists in other methods too, just wasn't noticed, or that S3 is tolerant of \ on some endpoints but not others?

Either way a quick fix should be initializing the prefixer in the S3 adapter's own constructor to make it use the / separator.

See the steps below for reproduction.

Steps To Reproduce

  • Be on Windows, easiest way to repro outside of Windows is to probably just replace the DIRECTORY_SEPARATOR constant referenced above with a '\\' as a literal value
  • Add 'root' => 'something', to the 's3' disk config in config/filesystems.php
  • Do:
    Storage::disk('s3')->put('foo.txt', 'bar');
    Storage::disk('s3')->temporaryUrl('foo.txt', now()->addMinutes(10));

You'll get a URL containing %5C (hex for \) which makes the URL invalid since the path to the object should be using /.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions