Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
a9db8a4
chore(docs): centralise changelog entries for unreleased versions
JarryShaw Oct 31, 2026
5a970bd
Merge remote-tracking branch 'origin/main' into wf/2483
JarryShaw Nov 1, 2026
db01d1b
docs(changelog): consolidate the 1.6.0 entries (#2449)
JarryShaw Nov 1, 2026
342baf3
Merge remote-tracking branch 'origin/main' into wf/2483-fold
JarryShaw Nov 1, 2026
4b93dc8
docs(changelog): fold the IGMP id() fix and review wording into 1.6.0…
JarryShaw Nov 1, 2026
2e23655
Merge remote-tracking branch 'origin/main' into wf/2483-fold-2
JarryShaw Nov 1, 2026
ccedecf
docs(changelog): fold main's latest merge wave into 1.6.0 (#2449)
JarryShaw Nov 1, 2026
a431c9b
Merge remote-tracking branch 'origin/main' into wf/2483-fold-3
JarryShaw Nov 1, 2026
521f750
docs(changelog): fold HTTP dispatch, docs pages and registry conventi…
JarryShaw Nov 1, 2026
78f8bac
Merge remote-tracking branch 'origin/main' into wf/2483-fold-4
JarryShaw Nov 2, 2026
42280b4
docs(changelog): fold DCCP, InARP's move and main's latest wave into …
JarryShaw Nov 2, 2026
ce11e08
Merge remote-tracking branch 'origin/main' into wf/2483-fold-5
JarryShaw Nov 2, 2026
5ac9441
docs(changelog): fold HTTP/2 frame chaining, SSLv3's module and main'…
JarryShaw Nov 2, 2026
0844898
Merge remote-tracking branch 'origin/main' into wf/2483-fold-6
JarryShaw Nov 2, 2026
ec47f7f
docs(changelog): fold TLS extensions and DTLS record chaining into 1.…
JarryShaw Nov 2, 2026
c87a95d
Merge remote-tracking branch 'origin/main' into wf/2483-fold-7
JarryShaw Nov 2, 2026
34f32f4
docs(changelog): fold IEEE 802.11 and the IP/TCP analysis functions i…
JarryShaw Nov 2, 2026
04c4be7
Merge remote-tracking branch 'origin/main' into wf/2483-fold-8
JarryShaw Nov 2, 2026
52c6ec3
docs(changelog): fold pad_length, the shared contextvars and the role…
JarryShaw Nov 2, 2026
140708f
Merge remote-tracking branch 'origin/main' into wf/2483-fold-9
JarryShaw Nov 2, 2026
7be4413
docs(changelog): fold Quick-Start's refusals, DTLS CIDs, 802.11 link …
JarryShaw Nov 2, 2026
ee56d13
Merge branch 'main' into chore/2449-centralize-changelog
JarryShaw Nov 2, 2026
8ab5026
docs(changelog): fold NoPayload's move, family-base dispatch and the …
JarryShaw Nov 2, 2026
42776b5
Merge remote-tracking branch 'origin/main' into fold11
JarryShaw Nov 2, 2026
777f708
docs(changelog): fold DTLS 1.3 connection IDs and the 1.5.0 HTTP role…
JarryShaw Nov 2, 2026
69b3186
Merge remote-tracking branch 'origin/main' into fold12
JarryShaw Nov 2, 2026
c90a125
docs(changelog): fold HTTP's versioned-base rules, the IGMP and GRE c…
JarryShaw Nov 2, 2026
319dd21
Merge remote-tracking branch 'origin/main' into fold13
JarryShaw Nov 2, 2026
cb68629
docs(changelog): fold the range-checked makers, the registry index, t…
JarryShaw Nov 2, 2026
24c2239
Merge remote-tracking branch 'origin/main' into fold14
JarryShaw Nov 2, 2026
c86fa42
docs(changelog): fold the internet makers' range checks and the cut H…
JarryShaw Nov 2, 2026
8f2961a
Merge remote-tracking branch 'origin/main' into fold15
JarryShaw Nov 2, 2026
25659fd
docs(changelog): fold radiotap's field decoding, the MH and DSS lengt…
JarryShaw Nov 2, 2026
e2d5c00
Merge remote-tracking branch 'origin/main' into fold16
JarryShaw Nov 2, 2026
285a838
docs(changelog): fold the MH option refusals, radiotap's mixed bitmap…
JarryShaw Nov 2, 2026
ebbe2ea
Merge commit '0c0794097' into fold17
JarryShaw Nov 3, 2026
d2aee5b
docs(changelog): fold make()'s enumeration fields, the corekit.schema…
JarryShaw Nov 3, 2026
083eee6
Merge commit '01f063467' into fold18
JarryShaw Nov 3, 2026
41f7e7e
docs(changelog): fold the makers' fixed-size octets, pcapkit.utilitie…
JarryShaw Nov 3, 2026
d85ffb0
Merge branch 'main' into chore/2449-centralize-changelog
JarryShaw Nov 3, 2026
e331c1a
docs(changelog): fold the makers' refusal of an empty raw item into 1…
JarryShaw Nov 3, 2026
dabd11c
Merge commit '07ceaf7c1' into fold20
JarryShaw Nov 3, 2026
554b3b8
docs(changelog): fold #2732 and #2734
JarryShaw Nov 3, 2026
206cdb0
Merge commit 'dea098b15' into fold21
JarryShaw Nov 3, 2026
e915af7
docs(changelog): fold #2735, #2736, #2737, #2741, #2742, #2744 and #2746
JarryShaw Nov 3, 2026
2f0e0b2
Merge commit 'f45c82b5d' into fold22
JarryShaw Nov 3, 2026
fb64180
docs(changelog): fold #2738 and the utilities.importlib rename
JarryShaw Nov 3, 2026
21bcc8e
Merge commit '1b4f9703e' into fold23
JarryShaw Nov 4, 2026
3bd890f
docs(changelog): fold #2752, #2753, #2754 and the ordering split
JarryShaw Nov 4, 2026
b853afe
Merge commit '73f730757' into fold24
JarryShaw Nov 4, 2026
fb56eae
docs(changelog): fold #2755, #2758 and #2759 (#2449)
JarryShaw Nov 4, 2026
5b1a352
Merge commit 'c211805ae' into fold25
JarryShaw Nov 4, 2026
ed294b4
docs(changelog): fold #2757 (#2449)
JarryShaw Nov 4, 2026
2f7e7b3
Merge commit 'e18d66e6f' into fold26
JarryShaw Nov 4, 2026
a066345
docs(changelog): fold #2764, #2765, #2766 and #2767 (#2449)
JarryShaw Nov 4, 2026
4353733
Merge commit '3c4b30e2b' into fold27
JarryShaw Nov 4, 2026
f865c75
docs(changelog): fold #2770 (#2449)
JarryShaw Nov 4, 2026
1818bb3
docs(changelog): correct the #2770 and #2767 entries (#2449)
JarryShaw Nov 4, 2026
342df58
Merge commit '7e6584786' into fold29
JarryShaw Nov 4, 2026
15bd0c2
docs(changelog): fold #2774 and #2775 (#2449)
JarryShaw Nov 4, 2026
0cd0d20
Merge commit '1c409b842' into fold30
JarryShaw Nov 4, 2026
9d57c18
Merge commit '812ed0fe2' into fold31
JarryShaw Nov 4, 2026
26a0389
docs(changelog): fold #2777, #2778, #2779 and #2781 (#2449)
JarryShaw Nov 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- [ ] [Searched](https://github.com/JarryShaw/PyPCAPKit/pulls?q=is%3Apr) for similar pull requests
- [ ] Followed the [coding style](https://github.com/JarryShaw/PyPCAPKit/blob/main/CONTRIBUTING.md#coding-style) (`make pylint`, `make mypy`, `make isort`)
- [ ] `make test` passes, and a test case covers the change
- [ ] Added a [changelog entry](https://github.com/JarryShaw/PyPCAPKit/blob/main/CONTRIBUTING.md#changelog-entries) under `docs/source/changelog/` and regenerated `CHANGELOG.md`, if the change is user-visible
- [ ] Described the user-visible change below and left its [changelog entry](https://github.com/JarryShaw/PyPCAPKit/blob/main/CONTRIBUTING.md#changelog-entries) to the maintainer, keeping `docs/source/changelog/` and `CHANGELOG.md` out of the diff, if the change is user-visible

### What is the purpose of your *pull request*?

Expand Down
144 changes: 140 additions & 4 deletions CHANGELOG.md

Large diffs are not rendered by default.

12 changes: 9 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ A rough outline:
- Create a topic branch, usually from `main`.
- Make commits of logical units, and add a test case if the change fixes a bug or adds functionality.
- Run the tests and make sure they pass (see below).
- Add a changelog entry if the change is user-visible (see below).
- If the change is user-visible, describe it in the pull request and leave its changelog entry to
the maintainer (see below).
- Make sure your commit messages are in the proper format (see below).
- Push your changes to a topic branch in your fork of the repository.
- Submit a pull request to the repo.
Expand Down Expand Up @@ -58,10 +59,15 @@ shapes of it at collection time and say what to do; `tests/_tiers.py` has the re
Entries live in `docs/source/changelog/<version>.rst`, one file per version, listed newest-first in
the toctree of `docs/source/changelog.rst`. That tree is the single source of the project's history.

**Pull requests for user-visible changes do not add their own bullet.** While a version is
unreleased, its entry is written centrally by the maintainer once a change is ready to merge or has
merged. Pull requests that each edit the same file conflict on every merge, so leave
`docs/source/changelog/<version>.rst` and `CHANGELOG.md` out of the diff.

**`CHANGELOG.md` is generated — never edit it by hand.** `util/changelog_md.py` derives it from the
newest entry alone, because its consumers (the `Create Release` workflow's release body and the
source distribution) read Markdown rather than reStructuredText. Add your bullet to the `.rst`
entry, then regenerate:
source distribution) read Markdown rather than reStructuredText. The maintainer adds the bullet to
the `.rst` entry, then regenerates:

```shell
python util/changelog_md.py # rewrite CHANGELOG.md from the newest entry
Expand Down
54 changes: 29 additions & 25 deletions docs/source/changelog/1.5.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,9 @@ Added
subclasses that are also a :class:`.MultiDict` and an :class:`.OrderedMultiDict`, so a
repeated key keeps every value. The data models' option lists use them (:issue:`1484`,
:pr:`1523`).
* :mod:`pcapkit.corekit.fields.byteorder`, holding ``packet_byteorder`` and
``byteorder_callback``, the byte-order helpers the PCAP and PCAP-NG schemas share
(:pr:`1528`, :issue:`1711`, :pr:`1715`).
* :mod:`pcapkit.corekit.fields.byteorder <pcapkit.corekit.schema.byteorder>`, holding
``packet_byteorder`` and ``byteorder_callback``, the byte-order helpers the PCAP and
PCAP-NG schemas share (:pr:`1528`, :issue:`1711`, :pr:`1715`).
* :func:`~pcapkit.corekit.io.can_seek`, whether a stream really seeks: on Windows a pipe
answers ``seekable()`` with ``True`` while its ``seek`` does nothing. It trusts
``seekable()`` only for a regular file or a stream with no descriptor.
Expand Down Expand Up @@ -1083,7 +1083,9 @@ Fixed
``except Exception`` handlers are never entered during the spin, and the memory is
the retry loop's ``EOF reached`` records, which the runner retains (:issue:`620`).
* ``register_protocol`` displaced one protocol class with another and said nothing.
The registry behind :data:`pcapkit.protocols.__proto__` is keyed on
The registry behind
:attr:`pcapkit.protocols.__proto__ <pcapkit.protocols.protocol.ProtocolBase.__registry__>`
is keyed on
``cls.__name__.upper()``, and several dispatchable classes are named ``HTTP``
(the base :class:`pcapkit.protocols.application.http.protocol.HTTP` and the ``httpv1`` and
``httpv2`` implementations), so a bare assignment decided the winner:
Expand Down Expand Up @@ -1143,8 +1145,8 @@ Fixed
``register_reassembly`` and ``register_traceflow`` on :class:`.Extractor`,
:meth:`.TraceFlow.register_dumper` (reached
through ``register_traceflow_dumper``), and
:func:`pcapkit.foundation.registry.protocols.register_protocol`. Each guard gains an
explicit ``isinstance(x, type)`` test ahead of its ``issubclass``; in those that
:func:`pcapkit.foundation.registry.protocols.register_protocol <pcapkit.foundation.registry.protocols.protocol.register_protocol>`.
Each guard gains an explicit ``isinstance(x, type)`` test ahead of its ``issubclass``; in those that
accept a :class:`.ModuleDescriptor` it runs after the descriptor is unwrapped, so a
descriptor naming a non-class attribute is rejected too, while ``register_protocol``
takes no descriptor. No guard's target class changes, and a wrong class still raises
Expand Down Expand Up @@ -1239,8 +1241,8 @@ Fixed
and ``register_transtype`` refuse a ``code`` that is not an enum member with
:exc:`.RegistryError` before touching a registry, where they registered it and then
raised ``AttributeError``, leaving the entry behind (:issue:`2186`, :pr:`2193`).
* :func:`pcapkit.foundation.registry.protocols.register_protocol_code`, and the
``code=`` class keyword, check every destination's key before registering any of
* :func:`pcapkit.foundation.registry.protocols.register_protocol_code <pcapkit.foundation.registry.protocols.protocol.register_protocol_code>`,
and the ``code=`` class keyword, check every destination's key before registering any of
them. A key belonging to another enum, such as ``{Frame: TransType.ICMP}``, is
refused with :exc:`.RegistryError` where it replaced the shipped
``LinkType.ETHERNET`` entry, and a bad target late in the list no longer leaves
Expand Down Expand Up @@ -1382,8 +1384,8 @@ Added
Inference refuses rather than guesses: an enum member whose type names no known
destination raises :exc:`.RegistryError`, and an unrecognised class keyword raises
:exc:`.UnsupportedCall`, matching the other registrar families. Backed by
:func:`pcapkit.foundation.registry.protocols.register_protocol_code`, also callable
directly for a class that declined at definition time. It was written up as the
:func:`pcapkit.foundation.registry.protocols.register_protocol_code <pcapkit.foundation.registry.protocols.protocol.register_protocol_code>`,
also callable directly for a class that declined at definition time. It was written up as the
mechanism :issue:`548` needs; :issue:`548` turned out to need a missing class instead
(115 is :rfc:`3931` L2TPv3 over IP, not :rfc:`2661`; see the corresponding **Fixed**
entry below), so its worked example names ``L2TPv3`` (:pr:`570`).
Expand Down Expand Up @@ -1510,12 +1512,13 @@ Changed
trailer bytes are not, so ``_decode_next_layer`` and ``_import_next_layer`` accept
the ``-1`` sentinel -- the rest of the packet, resolving to
:class:`~pcapkit.protocols.misc.raw.protocol.Raw`, or to
:class:`~pcapkit.protocols.misc.null.NoPayload` when nothing remains -- and
``__post_init__`` keeps a payload that ``read`` set instead of overwriting it with
:class:`~pcapkit.protocols.misc.null.NoPayload`. A real protocol number (any ``proto``
other than ``-1``) is still refused with :exc:`.UnsupportedCall`. A subclass that
calls either method with ``-1`` changes from raising to succeeding; no subclass in the
package does (:issue:`719`).
:class:`NoPayload <pcapkit.protocols.misc.no_payload.protocol.NoPayload>`
when nothing remains -- and ``__post_init__`` keeps a payload that ``read`` set
instead of overwriting it with
:class:`NoPayload <pcapkit.protocols.misc.no_payload.protocol.NoPayload>`.
A real protocol number (any ``proto`` other than ``-1``) is still refused with
:exc:`.UnsupportedCall`. A subclass that calls either method with ``-1`` changes
from raising to succeeding; no subclass in the package does (:issue:`719`).
* the :class:`~pcapkit.protocols.protocol.Protocol` and :class:`.ProtocolMeta`
docstrings. :class:`~pcapkit.protocols.protocol.Protocol` claimed to be the base of
every protocol family, though nothing in the package subclasses it, and
Expand Down Expand Up @@ -2271,21 +2274,21 @@ Fixed
``code=129``) was deleted once that registry defect was fixed as :issue:`690`.
``HIP_COPIES`` dropped to one as :issue:`689`, once :issue:`672` and :issue:`679` left
it routing around nothing.
* :class:`httpv1.HTTP <pcapkit.protocols.application.httpv1.protocol.HTTP>` raised a bare
* :class:`httpv1.HTTP <pcapkit.protocols.application.httpv1.protocol.HTTPv1>` raised a bare
exception for any payload that is not an HTTP/1 message, at these sites: the
header/body split in ``read``, the header's CRLF split and the start-line split in
``_read_http_header``, and ``item[1]`` on a field line with no colon.
:meth:`.HTTP._guess_version` falls through on :exc:`.ProtocolError` alone, so the
HTTP/1 attempt aborted the guess and the HTTP/2 arm below was dead code for each of
those inputs. Each site now raises :exc:`.ProtocolError`, which each method's
``Raises:`` section documented, and a test pins the invariant (nothing escapes
:class:`httpv1.HTTP <pcapkit.protocols.application.httpv1.protocol.HTTP>` that is not a
:class:`httpv1.HTTP <pcapkit.protocols.application.httpv1.protocol.HTTPv1>` that is not a
:exc:`.ProtocolError`), so any further bare-raising site would fail there. An obs-fold
continuation line [:rfc:`9112#section-5.2`] is legal HTTP/1 and is now unfolded, the
RFC's remedy, rather than read as a field of its own (with no colon it raised that
``IndexError``; with one it parsed into a spurious extra field). Reaching the HTTP/2
arm exposed a payload under nine octets to
:class:`httpv2.HTTP <pcapkit.protocols.application.httpv2.protocol.HTTP>`, where it usually
:class:`httpv2.HTTP <pcapkit.protocols.application.httpv2.protocol.HTTPv2>`, where it usually
fails inside the schema with a bare ``struct.error`` (not a ``ValueError``,
:exc:`.ProtocolError` or pcapkit :exc:`.StructError`, so uncatchable); ``read``
converts it and ``_guess_version`` suppresses it on the last arm only, since an arm
Expand All @@ -2310,8 +2313,8 @@ Fixed
``examples/generators/pcapng.py``'s ``_journal_entry`` cited a bare line number for
the defect its alignment workaround avoids and mis-attributed the fix; it now names
:issue:`678`'s ``not line.strip(b'\x00')`` guard and the mechanism (:issue:`791`).
* :meth:`.httpv2.protocol.HTTP.read` tested only the 24-bit declared length off the wire
(``schema.length < 9``), never how many octets the buffer held, so a frame backed by
* :meth:`httpv2.HTTP.read() <pcapkit.protocols.application.httpv2.protocol.HTTPv2.read>`
tested only the 24-bit declared length off the wire (``schema.length < 9``), never how many octets the buffer held, so a frame backed by
far fewer real octets than declared parsed and reported the declared,
attacker-controlled length. Sweeping the declared length against a four-octet buffer
gave non-monotone accept/reject (9, 15, 65535 and 16777215 parsed, 10 and 100 did
Expand Down Expand Up @@ -2374,7 +2377,7 @@ Fixed
safe heuristic, since a ``type <= 9`` guess misfires on binary HTTP/1 bodies).
Protochain over the sample captures is unchanged (:issue:`800`).
* :attr:`.TCP.__proto__` bound
:class:`httpv1.HTTP <pcapkit.protocols.application.httpv1.protocol.HTTP>` directly for ports 80
:class:`httpv1.HTTP <pcapkit.protocols.application.httpv1.protocol.HTTPv1>` directly for ports 80
and 8080, so a segment on either port was HTTP/1 by assertion of the port alone; both
versions share those ports, so the payload has to decide. Repointed to the generic
:class:`pcapkit.protocols.application.http.protocol.HTTP` proxy, whose identification became
Expand Down Expand Up @@ -2473,7 +2476,7 @@ Fixed
``[if_rxspeed]`` rather than ``[if_txspeed]``, and ``_read_option_epb_queue``'s length
guard says ``[epb_queue]`` rather than ``[epb_packetid]``. Only message text changes;
the exception and warning types are unchanged (:issue:`1038`).
* :class:`httpv1.HTTP <pcapkit.protocols.application.httpv1.protocol.HTTP>` refused every HTTP/1
* :class:`httpv1.HTTP <pcapkit.protocols.application.httpv1.protocol.HTTPv1>` refused every HTTP/1
message with no header fields, which [:rfc:`9112#section-2.1`] allows
(``*( field-line CRLF )``): ``b'GET / HTTP/1.0\r\n\r\n'`` raised
``ProtocolError: HTTP: invalid format``, because ``_read_http_header`` treated a
Expand Down Expand Up @@ -2610,8 +2613,9 @@ Fixed
the fabricated octets. :meth:`.IPv4.read` handed UDP the declared payload length when
nothing past the IPv4 header was captured, so ``test.pcapng`` frame 3 rebuilt with
8 invented UDP octets (:issue:`1167`). Every ``_import_next_layer`` now goes through
one guard: no captured octets gives :class:`~pcapkit.protocols.misc.null.NoPayload`,
and fewer than the next layer's ``__length_hint__`` gives
one guard: no captured octets gives
:class:`NoPayload <pcapkit.protocols.misc.no_payload.protocol.NoPayload>`, and fewer
than the next layer's ``__length_hint__`` gives
:class:`~pcapkit.protocols.misc.raw.protocol.Raw` unless the parsed header fits anyway, as a
12-octet L2TPv2 ZLB does. A header-only IPv6 packet is ``IPv6`` rather than
``IPv6:UDP:Raw``, and frame 3 is ``Ethernet:Raw``, rebuilt byte for byte
Expand Down
Loading
Loading