gh-158181: tarfile: raise ReadError instead of IndexError on a truncated GNU sparse header - #158183
Open
not-ekalabya wants to merge 2 commits into
Open
not-ekalabya wants to merge 2 commits into
not-ekalabya wants to merge 2 commits into
Conversation
… sparse header _proc_sparse() read the extended header block for a GNU sparse member with a plain read(BLOCKSIZE) instead of checking for a short/empty result, so a truncated archive whose sparse member has isextended set made nti() raise IndexError (s[0] on an empty buffer) instead of the documented ReadError. Raise ReadError directly when the read is short, matching the pattern used elsewhere in this module for truncated data.
BHUVANSH855
reviewed
Sep 25, 2026
BHUVANSH855
left a comment
Contributor
There was a problem hiding this comment.
Kindly sign the CLA, so that maintainers can begin with review process.
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.
Description
Fixes #158181.
_proc_sparse()reads the extended header block for a GNUGNUTYPE_SPARSEmember with a plaintarfile.fileobj.read(BLOCKSIZE),without checking for a short or empty result the way most other truncated-
data reads in this module do (see
copyfileobj'slen(buf) < bufsizecheck for the same pattern). A truncated archive whose sparse member has
isextendedset makes the parse loop callnti()on a short/empty buffer,and
nti()raisesIndexError(s[0]on empty input) rather than thedocumented
tarfile.ReadError, escaping everyexcept/tryinnext()/TarFile.__init__that's written against the documented contract.This raises
ReadError("unexpected end of data")directly when the read isshort, matching the exact pattern already used at
copy_or_raise/copyfileobjand several other call sites in this module.Found via
Found via an automated code-review pass using GLM-5.3-flash paired with
scopegrep, a semantic code-retrieval tool; independently re-verified and
fixed by hand.
Testing
I don't have a build of this checkout's CPython (this environment's
installed interpreter is 3.12, and main's stdlib already uses syntax/
builtins 3.12 can't parse -- e.g.
frozendict), so I could not runLib/test/test_tarfile.pydirectly. I verified the fix with a standaloneharness that loads
Lib/tarfile.pyviaimportlibagainst the system'salready-imported
re/shutil(to sidestep the_sreversion mismatch),with a minimal shim for the one new builtin the module needs at import
time:
isextended=1, no extended header block following) raisedIndexError: index out of rangefromnti(), reproducing the report.tarfile.ReadError: unexpected end of data.Please run the real test suite (particularly
Lib/test/test_tarfile.py'ssparse-file tests) as part of review, since I could not do so myself here.
Drafted with Claude Sonnet 5 (Anthropic); reviewed by @not-ekalabya before merge.