feat: zlib preset dictionary decompressor for S7CommPlus blobs#776
Open
gijzelaerr wants to merge 6 commits into
Open
feat: zlib preset dictionary decompressor for S7CommPlus blobs#776gijzelaerr wants to merge 6 commits into
gijzelaerr wants to merge 6 commits into
Conversation
) S7-1200/1500 PLCs compress XML metadata (tag definitions, interface descriptions, network comments, etc.) using zlib with Siemens-specific preset dictionaries. Python's zlib.decompress() returns Z_NEED_DICT for these blobs. This adds the 19 known dictionaries and a decompressor that auto-selects the correct one by Adler-32 checksum. The dictionaries were extracted from thomas-v2/S7CommPlusDriver (LGPL-3.0, BlobDecompressor.cs). Key dictionary for #757: IntfDescTag (0xce9b821b) — used for I/Q/M area tag definitions on V3 PLCs (S7-1200 FW V4.5+). New modules: - s7commplus/zlib_dicts.py — 19 preset dictionaries (24KB total) - s7commplus/blob_decompressor.py — decompress_blob() with auto dictionary lookup, find_and_decompress() for scanning raw payloads Replaces the partial oracle-based dictionary reconstruction in examples/browse_tags.py with complete, verified dictionaries. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The dictionaries are 100% printable XML template fragments (with the occasional German ü). Storing them as hex blobs made them unreadable. Now stored as Python string literals, encoded to bytes at import time. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace the 385-line Python module of string-chunked XML with 19
individual .xml files in s7commplus/zlib_dicts/. Each file is named
{adler32}_{name}.xml and can be read directly in any editor or IDE.
The __init__.py loader scans the directory at import time and builds
the same ZLIB_DICTIONARIES/ZLIB_DICT_NAMES dicts as before.
Also adds *.xml to pyproject.toml package-data so the files ship
in the wheel.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The end-of-file-fixer hook requires a trailing newline. The loader strips it with rstrip(b"\n") so the Adler-32 checksums stay correct. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The .xml dictionary files contain raw zlib preset dictionary bytes, not valid standalone XML. Mark them as binary in .gitattributes to prevent CRLF conversion on Windows (which broke Adler-32 checksums), and exclude them from the check-xml pre-commit hook. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add explore_xml() to both sync and async clients — sends an EXPLORE request and decompresses the zlib-compressed XML metadata from the response. Also export decompress_blob and find_and_decompress from the s7commplus package for direct use with raw EXPLORE payloads. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.
Summary
blob_decompressor.pywithdecompress_blob()that auto-selects the correct dictionary by Adler-32 checksumThe key dictionary for #757 is
IntfDescTag(Adler-320xce9b821b, 1178 bytes) — used for I/Q/M area tag definitions on V3 PLCs (S7-1200 FW V4.5+). With the complete dictionary, decompression produces clean XML that can be parsed with standard tools instead of regex extraction from garbled output.Addresses #757.
Test plan
find_and_decompress()scans raw payloads for zlib streams🤖 Generated with Claude Code