|
211 | 211 | from pcapkit.protocols.schema.misc.pcapng import zigbee_key_held |
212 | 212 | from pcapkit.protocols.schema.schema import Schema |
213 | 213 | from pcapkit.utilities.compat import StrEnum, localcontext |
| 214 | +from pcapkit.utilities.contextvars import frame_length |
214 | 215 | from pcapkit.utilities.datetime import fromtimestamp, totimestamp |
215 | 216 | from pcapkit.utilities.exceptions import (BaseError, EnumValueError, FormatError, ProtocolError, |
216 | 217 | StreamEOFError, UnsupportedCall, stacklevel) |
@@ -2666,8 +2667,13 @@ def _read_block_epb(self, schema: 'Schema_EnhancedPacketBlock', *, |
2666 | 2667 | warn(f'PCAP-NG: [Block {header.type}] captured length {schema.captured_len} runs past ' |
2667 | 2668 | f'the block, which holds {len(schema.packet_data)} octet(s); kept as captured', |
2668 | 2669 | ProtocolWarning, stacklevel=stacklevel()) |
2669 | | - return self._decode_next_layer(data, self._get_linktype(schema.interface_id), |
2670 | | - schema.captured_len) # type: ignore[return-value] |
| 2670 | + # NOTE: The layers below are told both lengths, as a PCAP frame tells them (#2653). |
| 2671 | + token = frame_length.set((data.captured_len, data.original_len)) |
| 2672 | + try: |
| 2673 | + return self._decode_next_layer(data, self._get_linktype(schema.interface_id), |
| 2674 | + schema.captured_len) # type: ignore[return-value] |
| 2675 | + finally: |
| 2676 | + frame_length.reset(token) |
2671 | 2677 |
|
2672 | 2678 | def _read_block_spb(self, schema: 'Schema_SimplePacketBlock', *, |
2673 | 2679 | header: 'Schema_PCAPNG') -> 'Data_SimplePacketBlock': |
@@ -2728,7 +2734,12 @@ def _read_block_spb(self, schema: 'Schema_SimplePacketBlock', *, |
2728 | 2734 | warn(f'PCAP-NG: [Block {header.type}] packet data of {data.captured_len} octet(s) ' |
2729 | 2735 | f'exceeds the original length of {data.original_len}; kept as captured', |
2730 | 2736 | ProtocolWarning, stacklevel=stacklevel()) |
2731 | | - return self._decode_next_layer(data, self._get_linktype(0), data.captured_len) # type: ignore[return-value] |
| 2737 | + # NOTE: The layers below are told both lengths, as a PCAP frame tells them (#2653). |
| 2738 | + token = frame_length.set((data.captured_len, data.original_len)) |
| 2739 | + try: |
| 2740 | + return self._decode_next_layer(data, self._get_linktype(0), data.captured_len) # type: ignore[return-value] |
| 2741 | + finally: |
| 2742 | + frame_length.reset(token) |
2732 | 2743 |
|
2733 | 2744 | def _read_block_nrb(self, schema: 'Schema_NameResolutionBlock', *, |
2734 | 2745 | header: 'Schema_PCAPNG') -> 'Data_NameResolutionBlock': |
@@ -3065,8 +3076,13 @@ def _read_block_packet(self, schema: 'Schema_PacketBlock', *, |
3065 | 3076 | warn(f'PCAP-NG: [Block {header.type}] captured length {schema.captured_length} runs past ' |
3066 | 3077 | f'the block, which holds {len(schema.packet_data)} octet(s); kept as captured', |
3067 | 3078 | ProtocolWarning, stacklevel=stacklevel()) |
3068 | | - return self._decode_next_layer(data, self._get_linktype(schema.interface_id), |
3069 | | - schema.captured_length) # type: ignore[return-value] |
| 3079 | + # NOTE: The layers below are told both lengths, as a PCAP frame tells them (#2653). |
| 3080 | + token = frame_length.set((data.captured_len, data.original_len)) |
| 3081 | + try: |
| 3082 | + return self._decode_next_layer(data, self._get_linktype(schema.interface_id), |
| 3083 | + schema.captured_length) # type: ignore[return-value] |
| 3084 | + finally: |
| 3085 | + frame_length.reset(token) |
3070 | 3086 |
|
3071 | 3087 | def _read_pcapng_options(self, options_schema: 'list[Schema_Option]') -> 'Option': |
3072 | 3088 | """Read PCAP-NG options. |
|
0 commit comments