fix: never leave trailing bytes when the output stream cannot be truncated - #232
Merged
Merged
Conversation
|
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
Changes
Follow-up to #221. A seekable output stream that cannot be truncated (
SetLengththrowsNotSupportedException) and still holds longer earlier content used to keep trailing bytes of that content after the document. For ODT the result was a corrupt file reported as success. The existing testSeekableOutputThatCannotChangeItsLength_IsWrittenWithoutTruncationcovered that behavior and is replaced.New behavior: the stream is truncated before anything is written. If it cannot be truncated, processing returns a Failure and the output is left unchanged.
OdtPackage.Save): the package is already built in memory, so its length is known. Ifoutput.CanSeekand the earlier content afterPositionis longer than the package, the output is truncated atPositionbefore the package is written. If truncation is not supported,Savethrows the new internalOutputStreamNotTruncatableExceptionand nothing is written, which keeps the "nothing written on failure" contract. If the package is at least as long as the earlier tail, it overwrites all of it, soSetLengthis not needed and non-truncatable streams keep working. Non-seekable outputs are unchanged. The old post-writeTruncateAfterPosition, which silently swallowedNotSupportedException, is removed.DocumentTemplateProcessor): the perf(odt): stream unprocessed package entries, bound XML part sizes, truncate seekable outputs #221 truncation now runs before the template copy, not after it. With a non-truncatable output that holds earlier content, processing fails before anything is written and the earlier content stays as it was. Before, the template was copied over part of it and the result wasProcessing failed: Specified method is not supported.DOCX already neededSetLengthin practice: OpenXML/ZipArchive update mode calls it on save even for an empty output, so an empty non-truncatable output still fails there, as before. The edit-in-place contract for DOCX does not change.TemplateProcessorfacade, return the same message:Invalid output stream: the output stream has earlier content after the current position that would remain after the document, and it cannot be truncated (SetLength is not supported). Pass an empty output stream or one that supports SetLength (for example a FileStream opened with FileMode.Create).opendocument.md(output requirements, memory use) andquick-start.md(DOCX output streams).Tests
OdtPackageBranchTests): non-truncatable output with longer earlier content → Failure, bytes unchanged, directly and through the facade. Non-truncatable output with shorter earlier content → success andSetLengthis never called. Fixed-sizeMemoryStream(can shrink) with longer content → truncated and valid.StreamValidationTests): non-truncatable output with earlier content → Failure, bytes unchanged, directly and through the facade. Shorter earlier content → truncated and valid. The existingExistingLongerOutputFile_IsTruncatedtests for both formats still pass.-p:ContinuousIntegrationBuild=true(0 warnings), all test projects on net10/9/8,dotnet format --verify-no-changes,dotnet pack,mkdocs build --strict.Public API impact
None: no public API change. Behavior change only for seekable, non-truncatable output streams with earlier content. They now get a Failure instead of a corrupt output (ODT: previously a false success; DOCX: previously a failure after partially overwriting the stream).