UFAL/fix: S3 presigned-URL Content-Disposition — spaces became '+', raw non-ASCII in filename param - #1371
Open
milanmajchrak wants to merge 3 commits into
Open
UFAL/fix: S3 presigned-URL Content-Disposition — spaces became '+', raw non-ASCII in filename param#1371milanmajchrak wants to merge 3 commits into
milanmajchrak wants to merge 3 commits into
Conversation
(cherry picked from commit fe4077a)
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Ports the allzip fix from customer/zcu-data (#1267) to dtq-dev and aligns the fork's own endpoints with the encoding vanilla now uses. The allzip endpoint still built its header with a bare `attachment;filename="<name>"`, so item names with diacritics reached the browser mangled and names containing a double quote closed the quoted-string early (ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION). MetadataBitstreamController and BitstreamByHandleRestController have no counterpart upstream, so each carries its own private copy of vanilla's createFallbackAsciiName / createEncodedUtf8Name rather than a shared fork utility. Copying keeps every endpoint tracking upstream behaviour and adds no fork-invented API to maintain. HttpHeadersInitializer stays byte-identical to vanilla and keeps its own copy for the same reason. One deliberate deviation from vanilla, marked in both copies: the ASCII fallback escapes \ and ". Vanilla omits this, so a name containing a quote closes the quoted-string early — exactly the bug #1267 was raised for. Because the fallback now transliterates instead of blanking out, BitstreamByHandleRestControllerIT expects "Media (3).jfif" where it used to expect "M_di_ (3).jfif". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
milanmajchrak
force-pushed
the
ufal/fix-content-disposition-rfc5987
branch
from
July 16, 2026 10:59
fcdb270 to
1e1b1fe
Compare
…n-ASCII in filename
The S3 direct-download path built its own header and had two defects:
- URLEncoder.encode without the "+" -> "%20" fixup, so a space in the name
arrived as a literal plus sign in filename*
- the ASCII fallback only replaced CR, LF and quotes, leaving raw non-ASCII
bytes in the filename param, which is ISO-8859-1 only
Both are fixed by copying vanilla's createFallbackAsciiName /
createEncodedUtf8Name into this class, the same way the other fork-only
endpoints do. This class has no upstream counterpart, so copying costs nothing
and keeps its behaviour tracking vanilla.
Two deviations from vanilla are kept, both of them behaviour this class already
had and both marked in the code: CR/LF are dropped to prevent header injection,
and \ and " are escaped so a quoted name cannot close the string early.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
milanmajchrak
force-pushed
the
ufal/fix-s3-presigned-filename
branch
from
July 16, 2026 11:04
12f35c0 to
e99c57d
Compare
milanmajchrak
changed the base branch from
ufal/fix-content-disposition-rfc5987
to
dtq-dev
July 16, 2026 11:45
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two defects in the S3 direct-download path, both spotted while doing #1368.
1. Spaces became
+URLEncoderis form encoding, which differs from RFC 5987 on exactly one character: it emits+for a space where RFC 5987 wants%20. A client decodingfilename*strictly getsmy+file.txt. The other fork call sites already had the.replace("+", "%20")fixup; this one never did.2. Raw non-ASCII left in the
filenameparamOnly CR, LF and quotes were replaced, so
Příliš.pdfwent into thefilenameparam as raw UTF-8 bytes. That param is ISO-8859-1 only — the same bug class #1368 fixes elsewhere.Both are fixed by copying vanilla's
createFallbackAsciiName/createEncodedUtf8Nameinto this class, the way the other fork-only endpoints do.S3DirectDownloadServiceImplhas no upstream counterpart, so copying costs nothing and keeps its behaviour tracking vanilla. No shared fork helper is introduced.Deviations from vanilla — both pre-existing behaviour of this class, both marked in code
[^\x00-\x7F]only removes characters outside 00–7F, and CR/LF are inside), so copying it verbatim would have removed an existing protection.\and"are escaped — vanilla omits this, and a quoted name breaks the header.Other control characters, tab included, still pass through exactly as before this PR, so
weirdFilenamekeeps its existing assertions unchanged.Verified
mvn test-compileondspace-api— passmvn checkstyle:checkondspace-api— 0 violationsS3DirectDownloadServiceTestcould not be run locally. It extendsAbstractUnitTest, which boots the DSpace kernel, and the kernel fails to start in my checkout (No qualifying bean of type 'org.dspace.core.ProvenanceService') becausetarget/testingis unpacked from a staletestEnvironment.zipin the local~/.m2, and rebuilding that artifact needs a full root build. The identical failure reproduces on unmodifiedorigin/dtq-dev, so it is environmental rather than caused by this change — but it does mean my edits to that test file are unverified and need CI to confirm them, in particular the newspacesAndDiacriticsInFilenameassertion.🤖 Generated with Claude Code