Skip to content

Commit d25abe4

Browse files
Release v0.7.0
1 parent 4cfcc8e commit d25abe4

2 files changed

Lines changed: 30 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,35 @@ All notable changes to this extension will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [0.7.0] - 2026-06-10
9+
10+
### Added
11+
12+
- `deepclone_to_array()` / `deepclone_from_array()` now round-trip closures
13+
declared in constant expressions (PHP 8.5+: attribute arguments, class
14+
constants, enum cases, property and parameter defaults, and property hooks).
15+
Such closures are compile-time-checked to be static and capture-free, so
16+
they carry no state and are encoded by their declaration site (a new mask
17+
marker) rather than by code. `deepclone_from_array()` re-evaluates the
18+
addressed constant expression, selects the closure by a depth-first index,
19+
and verifies the declaration line still matches, so a payload that outlived a
20+
code change fails loudly with a "stale payload" error instead of resolving to
21+
a moved closure. The payload carries names and indices only, never code;
22+
`allowed_classes` gates both directions (`Closure` to encode, the declaring
23+
class to decode). Closures created at runtime, and any the scanner cannot
24+
match, keep throwing `\DeepClone\NotInstantiableException` as before.
25+
26+
### Fixed
27+
28+
- `deepclone_from_array()` now rejects, with a `\ValueError`, a payload that
29+
creates an object of a class with `__unserialize()` without flagging it for
30+
its negative-wakeup state replay. Such a crafted payload previously built a
31+
bare `object_init_ex()` shell that `__unserialize()` never initialized; for
32+
`BcMath\Number` the `bc_num` stays `NULL` and any operation on it crashed.
33+
`deepclone_to_array()` only ever emits such a class with the replay flag, so
34+
well-formed payloads are unaffected (php/php-src#22259 proposed an engine-side
35+
guard but was declined, as the state is unreachable from userland).
36+
837
## [0.6.1] - 2026-06-09
938

1039
### Fixed

php_deepclone.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
extern zend_module_entry deepclone_module_entry;
55
#define phpext_deepclone_ptr &deepclone_module_entry
66

7-
#define PHP_DEEPCLONE_VERSION "0.6.1"
7+
#define PHP_DEEPCLONE_VERSION "0.7.0"
88

99
ZEND_BEGIN_MODULE_GLOBALS(deepclone)
1010
HashTable hydrate_cache;

0 commit comments

Comments
 (0)