Redis implemented new CAS semantics which work both with values and the
XXH3 digest of those values.
This commit implements the Redis command itself and a helper which
computes the XXH3 digest locally. Note that we can only be sure to have
the `XXH3` hashing algorithm in PHP >= 8.1 so the `_digest` helper is
limited to PHP 8.1 or newer.
```c
int pos, i;
memcpy(&pos, key, sizeof(pos));
pos %= pool->totalWeight;
```
As unlikely as it is, this may cause UB if user's are generating their
own session IDs shorter than three bytes. This commit checks the session
id length and only copies in the bytes that we have.
Technically this could change behavior for session ID's of length 2 or
less, but this seems acceptable because currently such an ID would end
up selecing a server at random, depending on whatever bytes were past
the end of the `zend_string`.
In a future release we will fix this logic to use all of the entropy of
the session ID as well as ensure `pool->totalWeight` is > 0.
Add a specific warning when we can't parse any servers from
`php.session_save_path`.
PHP will then display the save path, but this will let users know there
was a problem parsing the path.
Fixes#1390
Signed-off-by: michael-grunder <michael.grunder@gmail.com>
The warning when a user picks an unsupported session compression
algorithm was pretty confusing.
The new message tells the user if the selection was invalid or only
invalid because the redis.so wasn't built with support.
Fixes#2570
We were incorrectly ignoring errors when calling `is_numeric_string`,
meaning we would truncate hash fields that had integer prefixes.
```php
$redis->hmget('hash', ['123notaninteger']);
// Would actually execute:
// HMGET hash 123
```
Fixes#2731
Conditionally add `[[nodiscard]]` (c23) or
`__attribute__((warn_unused_result))` when the compiler supports it.
This commit initially just adds iit to `cluster_map_keyspace` but we can
go throughour API adding it where appropriate.
When a Redis Cluster failover occurs, the client detects that the
redirected node was a replica of the old master and calls
cluster_map_keyspace() to remap the cluster topology.
If cluster_map_keyspace() fails (e.g., due to network issues during
the remap), it frees all node objects via zend_hash_clean(c->nodes)
and zeros the master array via memset(c->master, 0, ...).
The bug was that the return value of cluster_map_keyspace() was being
ignored in the failover detection path. This caused the code to
continue with NULL socket pointers, leading to segfaults when
dereferencing c->cmd_sock later.
This fix:
1. Checks the return value of cluster_map_keyspace() in failover
detection and returns FAILURE if it fails
2. Adds defense-in-depth NULL checks after MOVED and ASK redirections
to prevent segfaults if slots become NULL for any reason
Fixes production crashes observed during Redis Cluster failovers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
We've basically maintained `package.xml` by hand all these years which
makes it a pretty big pain to do a new release. This commit uses a small
utility program to normalize the spacing with PHP's simplexml extension.