Repository navigation
fix(extraction): accept a file object without a name as fin (#1506) - #1509
Conversation
|
Verdict: NEEDS CHANGES at Required: with an unnamed stream, What checked out:
|
`fin` is typed and documented as `str | IO[bytes]`, but an `io.BytesIO` crashed before parsing: - `Extractor.make_name` read `fin.name`; a stream without a `str` name is now labelled after its type, e.g. `<BytesIO>`. Output names come from `fout` alone, so nothing else depends on it. - the magic number and the PCAP-NG block type are read with `peek`, which `IO[bytes]` lacks; a seekable stream without one is wrapped in `_PeekableStream`, a read-and-seek-back shim with no finaliser, so the caller's stream is never closed behind their back (#610). - scapy, pyshark, pypcap and pcap_ct open `_ifnm` as a path, so with an unnamed stream they would open the `<BytesIO>` label as a file; they now refuse it with `UnsupportedCall` before the engine runs.
45a2938 to
d97bc17
Compare
|
Verdict: GOOD TO GO at
|
Please follow the guide below
You will be asked some questions, please read them carefully and answer honestly
Put an
xinto all the boxes [ ] relevant to your pull request (like that [x])Use Preview tab to see how your pull request will actually look like
Searched for similar pull requests
Followed the coding style (
make pylint,make mypy,make isort)make testpasses, and a test case covers the changeAdded a changelog entry under
docs/source/changelog/and regeneratedCHANGELOG.md, if the change is user-visible — N/A — centralised in docs(changelog): shared 1.5.0 changelog — long-lived, merges last (#610, #616, #617, #618, #620) #657What is the purpose of your pull request?
Tick the commit type your subject line carries.
fix— corrects a defectfeat— adds a featureperf— changes performance, not behaviourrefactor— changes neither behaviour nor performancetest— tests onlydocs— documentation onlyci— workflows or build toolingrelease— bumps the version or rolls up a distributionchore— anything elseDescription of your pull request and other information
finis typedstr | IO[bytes]and documented as "file name to be read or a binary IO object" on bothextract()andExtractor, so streams are in the contract. Anio.BytesIOhit two crashes in a row, and the path-based engines a third:make_namereadfin.name. A stream without astrname (none, or theintof a descriptor-backed file) is now labelled<BytesIO>-style. Output names come fromfoutalone, sonofile=False, fout=Nonewritesout.<ext>as for a path — no error needed.peek, whichIO[bytes]lacks. A seekable stream without it is wrapped in_PeekableStream, a read-and-seek-back shim with no finaliser, so the caller's stream stays open (Extractor._cleanup closes the caller-supplied stream and leaks the file it opened itself #610)._ifnmto their library as a path, so an unnamed stream would open the<BytesIO>label as a file (FileNotFoundErrorfromengines/scapy.py:182).Extractor.__init__now refuses these withUnsupportedCall, worded like the existing pypcap/pcap_ct refusal, before the engine runs. dpkt, pypcapfile and the default engine read_ifileand keep working; a stream with a realstrname is not refused.New
tests/foundation/test_extraction_unnamed_stream_unit.py, 9 tests: 8 fail onorigin/main'sextraction.py, and the scapy and pyshark refusal cases fail on the previous revision (45a293871); all 9 pass here. pyshark rules itself out on CPython 3.14, so its case clearsunsupported_reasonto test the refusal itself.tests/foundation,tests/interface,tests/projectandtests/test_docstring_contract.pypass after rebasing ontoa608b6e83.Closes #1506