Repository navigation
Releases: RezaKargar/go-igbinary
Release list
v0.3.3
Documentation and repository-metadata release. No code or API changes — the decoder behaves exactly as in v0.3.2, so upgrading is optional.
This release makes the project easier for AI coding agents (and new contributors) to find, orient in, and change safely.
Agent onboarding
.cursor/rules/is now tracked in git instead of being excluded by.gitignore, so the shared git-commit conventions actually ship with the repository.AGENTS.mdalready documented these rules as present — now they really are.- Added
.github/copilot-instructions.mdas a GitHub Copilot entrypoint that points atAGENTS.md. AGENTS.mdis now explicitly the single source of truth, withCLAUDE.md, the Copilot instructions, and the Cursor rules as thin pointers back to it.
AGENTS.md accuracy
- Repository map expanded:
memcached/is broken out per file, includingfastlz2.go(the self-contained FastLZ level-2 decompressor added in v0.3.2), andintegration/contents are described. - Corrected the root-package standard-library import list (
strconvwas missing) and documented the single permitted library dependency inmemcached/. - Documented what CI actually runs, added the release process, and added a FastLZ troubleshooting entry to the task-routing section.
Discoverability
- Repository topics and a
pkg.go.devhomepage link were added so the module surfaces in GitHub and package-index searches.
Full changelog: v0.3.2...v0.3.3
v0.3.2
fastlz level 2 support
PHP's fastlz_compress switches from level 1 to level 2 for inputs ≥ 64 KB, and fastlz_decompress selects the decoder from the stream's first byte. The underlying dgryski/go-fastlz decoder implements level 1 only, so large memcached payloads (e.g. > 64 KB) failed with fastlz: corrupt input.
This release adds a pure-Go port of the reference fastlz2_decompress and dispatches to it based on the level encoded in the stream; level 1 continues to use go-fastlz.
- No new dependencies (stdlib only)
- Verified against the reference C implementation; the level-2 golden vector in testdata round-trips
- Test suite stays cgo-free
v0.3.1
v0.3.0
What's New
NormalizeArrays — Convert PHP sequential maps to Go slices
PHP does not distinguish indexed arrays from associative arrays at the igbinary level — both are encoded as key-value maps. A PHP indexed array like ["a","b","c"] decodes as map[string]any{"0":"a","1":"b","2":"c"}.
NormalizeArrays recursively converts such maps back into []any slices so that JSON serialization produces JSON arrays instead of JSON objects.
Usage
// Option A: manual post-processing
val, _ := igbinary.Decode(data)
val = igbinary.NormalizeArrays(val)
// Option B: automatic via decoder option
dec := igbinary.NewDecoder(igbinary.WithNormalizeArrays())
val, _ := dec.Decode(data) // sequential maps are already []anyRules
- Empty maps →
[]any{} - Maps with keys
"0","1",…,"N-1"→[]anyof length N (recursive) - All other maps → left as-is, values recursively normalized
- Non-map/non-slice values → unchanged
Full Changelog: v0.2.1...v0.3.0
v0.2.1
Bug Fix
- fix: do not register TypeStringEmpty in string dedup table — PHP igbinary treats
TypeStringEmpty(0x0D) as a special marker that does not occupy a slot in the string deduplication table. The previous implementation incorrectly registered empty strings in bothdecodeValue()anddecodeArrayKey(), causing all subsequentStringIDlookups to be off by one whenever an empty string appeared in the data. This manifested as corrupted keys in structures like badge payloads where empty string values are common and later entries reference previously registered strings by ID.
Tests
- Added 4 test cases covering the empty string dedup table behavior:
TestEmptyStringValueDoesNotShiftStringIDs— empty value followed by StringID referenceTestEmptyStringKeyDoesNotShiftStringIDs— empty key followed by StringID referenceTestMultipleEmptyStringsDoNotShiftStringIDs— multiple empty strings (key + value)TestEmptyStringInNestedStructDoesNotShiftStringIDs— real-world badge-like nested structure
CI
- Fixed Go version in test matrix (1.25 → 1.26) to match go.mod requirement
- Fixed gofmt alignment in test cases
v0.2.0
What's Changed
Bug Fix: Array/Object Reference Resolution
The igbinary decoder previously discarded TypeArrayRef and TypeObjectRef back-reference IDs, always returning nil. This caused PHP values that share the same underlying zval (via copy-on-write semantics) to decode as nil in Go.
Root cause: When PHP assigns the same array to multiple keys without modification, igbinary serializes the first occurrence as a full array and subsequent occurrences as back-references (TypeArrayRef). The Go decoder was reading but discarding these reference IDs.
Changes
- Added a compound value reference table (
values []any) to the decoder's reader struct - Arrays and objects are registered in the table before populating their contents (supports circular references)
decodeRefnow resolves references by looking up the table index instead of returningnil- Added
ErrValueRefOutOfRangesentinel error for invalid reference IDs - Updated and added comprehensive tests for reference resolution scenarios
- Bumped Go version to 1.26.0
Impact
This fix affects any PHP data where the same array or object is assigned to multiple locations within a single igbinary-serialized blob. All such cases are now correctly resolved.
v0.1.0 - Initial Release
go-igbinary v0.1.0
Pure Go decoder for PHP's igbinary serialization format.
Features
- Zero external dependencies for the core
igbinarypackage (stdlib only) - Decodes all igbinary v2 types: strings, integers, floats, booleans, nil, arrays, objects
- String deduplication support (igbinary's compact string table)
- PHP object decoding with class name preservation (
__classkey) - Class inheritance support (parent properties are flattened)
memcached sub-package
- Full PHP memcached interop via flag-based dispatch
- Built-in compressors: FastLZ, Zlib
- Built-in serializers: igbinary, JSON, String, Long, Double, Bool
- Pluggable
CompressorandSerializerinterfaces for custom implementations - Builder pattern for codec configuration
Installation
go get github.com/RezaKargar/go-igbinary@v0.1.0Test Coverage
- 93%+ overall test coverage
- 88 unit tests + 21 integration tests (PHP writes to memcached, Go reads and decodes)
- Docker-based integration tests (test-only dependency, not required by the library)