[6.x] Encode asset URLs - #15146
Conversation
`Asset::url()` and `Asset::absoluteUrl()` returned the raw path, so filenames containing spaces or accents produced invalid urls. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Keeps encoded urls resolving back to their asset. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jasonvarga
left a comment
There was a problem hiding this comment.
URL::encode() (src/Facades/Endpoint/URL.php:326-346) was built for encoding a URL that may already be partially percent-encoded — it rawurlencode()s and then maps a set of sequences (%2F, %40, %3A, ... %25→%) back to their literal characters so it doesn't double-encode an already-encoded URL. Reusing it here on a raw filesystem path (Asset.php's url()/absoluteUrl()) breaks that assumption: if a filename already contains a literal %XX-looking substring, it gets treated as "already encoded" and passes through untouched.
Repro: an asset with the literal filename photo%20one.jpg:
Asset::url()encodes it to.../photo%20one.jpg— unchanged, since the existing%20is preserved as if it were already an encoded space.AssetRepository::findByUrl()'s newrawurldecode()then turns that intophoto one.jpg, which doesn't match the actual stored pathphoto%20one.jpg. The asset becomes unresolvable via theurl()→findByUrl()round trip.
This is narrow (filenames containing literal percent-encoded-looking sequences), but it's a real regression — these assets resolved fine before this change since neither side encoded/decoded. None of the added test cases (nothing to encode, spaces, accents, spaces in folders) cover a literal %XX substring, so it's not caught by CI.
Needs fixing before merge: don't reuse URL::encode() (designed for full URLs) on raw asset paths. A plain per-segment rawurlencode() — without the "preserve already-encoded" table — would round-trip correctly through rawurldecode() for all inputs, since it never assumes the raw path is pre-encoded.
This pull request fixes an issue where asset URLs weren't encoded, so filenames containing spaces or accented characters produced invalid URLs.
This was happening because
Asset::url()andAsset::absoluteUrl()assembled the URL from the raw path, leaving characters likeúand spaces untouched. An asset calledDún Laoghaire_18 2.jpgcame back ashttps://ams3.digitaloceanspaces.com/mywebsite/Dún Laoghaire_18 2.jpg, whichStr::isUrl()doesn't consider a URL. Browsers percent-encode a rawsrcattribute for you, so images still rendered — the breakage only showed up server-side, where passing the URL into something like theGlidetag would send it down the wrong branch.This PR fixes it by running the path through
URL::encode()when assembling both URLs. This PR also decodes the path inAssetRepository::findByUrl(), so encoded URLs still resolve back to their asset.Fixes #5593