Fix ArgumentException on NZB titles containing quote characters - #837
Open
lisim wants to merge 1 commit into
Open
Fix ArgumentException on NZB titles containing quote characters#837lisim wants to merge 1 commit into
lisim wants to merge 1 commit into
Conversation
Release titles containing " (very common in usenet subject lines, e.g. embedded sub-titles) crashed the SABnzbd add-file submission with System.ArgumentException from ContentDispositionHeaderValue, because GenericUsenetSourceResolver.SanitizeFileName() only stripped filesystem-invalid characters and left '"'/'\\' untouched. Those are valid on Linux/macOS filesystems but break the multipart Content-Disposition "filename" quoting used when submitting to SABnzbd, so the download silently never reached the client. Fixes Listenarrs#808. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
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.
Summary
Fixes #808.
Release titles containing
"(very common in usenet subject lines — embedded sub-titles, part numbers, etc.) crash the SABnzbd add-file submission withSystem.ArgumentExceptionthrown fromContentDispositionHeaderValue.EncodeAndQuoteMime, before the request ever reaches SABnzbd. The download silently disappears (the provisional download record is removed on submission failure).Root cause:
GenericUsenetSourceResolver.SanitizeFileName()only strips characters invalid for a filesystem filename (Path.GetInvalidFileNameChars()— on Linux/macOS this is essentially just/)."and\are valid filesystem characters there, so they pass through untouched, but this filename is then used as the multipartContent-Dispositionfilenameparameter when POSTing to SABnzbd'saddfileendpoint (SabnzbdAddWorkflow.AddAsync), and .NET's header-value quoting can't safely encode an unescaped".Note SABnzbd's actual displayed title comes from the separate
nzbnamequery parameter (SabnzbdAddRequestPlanner.BuildFileQueryParams), not from this multipart filename, so sanitizing it further has no user-visible effect beyond fixing the crash.Changes
Fixed
GenericUsenetSourceResolver.SanitizeFileName()now also replaces"and\with_, alongside the existing filesystem-invalid-character check.Added
AddAsync_TitleContainsQuotesAndCommas_SendsNzbWithoutHeaderEncodingErrorinSabnzbdAdapterTests.cs, using the real-world failing title from Failed to add nzb with " (or other non-ASCII charachters) in name #808/production logs, asserting the full resolve → submit pipeline succeeds.addfilemode handler onSabnzbdApiMock(previously onlyversion/history/queuewere handled; nothing exercised the add-file submission path via the shared mock).Testing
I couldn't get a clean local
dotnet testrun for this test class — on this environment, every test inSabnzbdAdapterTests(18/18, including unrelated pre-existing ones) fails atInitializeAsync→AddAuthorizedRootAsyncwithPathIdentityStateExpected: Valid, Actual: Unavailable, when run inside a stockmcr.microsoft.com/dotnet/sdk:10.0container (tried both a plaindocker runand one with--cap-add SYS_ADMIN --security-opt seccomp=unconfined; same result either way). I confirmed this is pre-existing and unrelated to this change by running the identical test file against unmodifiedcanaryHEAD in the same container — 17/17 fail the same way there too. Per.github/AGENTS.md's own guidance ("a test skipped on the current host does not validate that platform... confirmed by the authoritative native Linux CI run"), I'm relying on CI for this test class rather than trying to fix an unrelated sandboxing limitation in this PR.To still get direct proof the actual fix works, I wrote a standalone throwaway console app (not part of this PR) that calls
GenericUsenetSourceResolver.ResolveAsyncwith the exact failing title from #808 and then performs the sameMultipartFormDataContent.Add(fileContent, "name", submission.FileName)callSabnzbdAddWorkflowmakes:Against unmodified
canaryHEAD: reproduces the exact reported exception verbatim —ArgumentException: The format of value 'DBS #0762 "J.K. Rowling - Harry Potter 1-7 Audio Book (english)" - "Audio book - Harry Potter And The Deathly Hallows - J.K. Rowling.part01.rar" (02_22) - 672,05 MB.nzb' is invalid.Against this branch:
Resolved FileName: DBS #0762 _J.K. Rowling - Harry Potter 1-7 Audio Book (english)_ - _Audio book - Harry Potter And The Deathly Hallows - J.K. Rowling.part01.rar_ (02_22) - 672,05 MB.nzb→PASS: MultipartFormDataContent.Add did not throw.dotnet build listenarr.slnx— clean, 0 errors.dotnet format listenarr.slnx --no-restore --verify-no-changes --include <the 3 changed files>— clean, no formatting changes needed.Review coverage (per
.github/AGENTS.md)Path.GetInvalidFileNameChars()already differs between Windows and Unix; the two added characters (",\) are additionally unsafe on both because the failure mode is in the HTTP header layer, not the filesystem layer, so this fix is platform-independent by construction.