Clean up lookahead-related code#3
Conversation
Co-authored-by: Ozan Tezcan <ozantezcan@gmail.com>
Code Review by Qodo
1. slot_buffer uses malloc/free
|
| int *slot_buffer = malloc(sizeof(int) * keys_result->numkeys); | ||
|
|
||
| for (int j = 0; j <= keys_result->numkeys; j++) { | ||
| robj *this_key = argv[keys_result->keys[j].pos]; | ||
| int this_slot = (int)keyHashSlot((char*)this_key->ptr, sdslen(this_key->ptr)); | ||
| slot_buffer[j] = this_slot; | ||
|
|
||
| if (first_slot == INVALID_CLUSTER_SLOT) | ||
| first_slot = this_slot; | ||
| else if (first_slot != this_slot) { | ||
| return INVALID_CLUSTER_SLOT; | ||
| free(slot_buffer); | ||
| return CLUSTER_CROSSSLOT; | ||
| } | ||
| } | ||
| free(slot_buffer); |
There was a problem hiding this comment.
1. slot_buffer uses malloc/free 📘 Rule violation ⛯ Reliability
• extractSlotFromKeysResult() allocates slot_buffer with malloc() and releases it with free() inside src/, which bypasses Redis memory tracking. • This violates the requirement to use zmalloc/zfree wrappers for dynamic memory management in src/ code paths.
Agent prompt
## Issue description
`src/cluster.c` uses `malloc()`/`free()` in `src/`, which violates the Redis requirement to use `zmalloc`-family wrappers for allocation and tracking.
## Issue Context
The function `extractSlotFromKeysResult()` allocates a temporary `slot_buffer` using libc allocation.
## Fix Focus Areas
- src/cluster.c[1109-1124]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| for (int j = 0; j <= keys_result->numkeys; j++) { | ||
| robj *this_key = argv[keys_result->keys[j].pos]; | ||
| int this_slot = (int)keyHashSlot((char*)this_key->ptr, sdslen(this_key->ptr)); | ||
| slot_buffer[j] = this_slot; |
There was a problem hiding this comment.
2. j <= numkeys out-of-bounds 📘 Rule violation ✓ Correctness
• The loop iterates with j <= keys_result->numkeys, which executes one extra iteration beyond the valid keys_result->keys[] and slot_buffer[] bounds. • This is a boundary-value handling bug that can cause out-of-bounds reads/writes and crashes when processing keys (especially when numkeys is small).
Agent prompt
## Issue description
`extractSlotFromKeysResult()` iterates one element past the end of the `keys_result->keys` array and the `slot_buffer` array due to `j <= keys_result->numkeys`.
## Issue Context
This is a boundary/edge-case bug that can lead to memory corruption or crashes.
## Fix Focus Areas
- src/cluster.c[1112-1115]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
| if (num_keys > 0) { | ||
| *slot = extractSlotFromKeysResult(argv, result); | ||
|
|
||
| } |
There was a problem hiding this comment.
3. *slot left uninitialized 📘 Rule violation ✓ Correctness
• extractKeysAndSlot() only assigns *slot when num_keys > 0, leaving *slot unchanged for num_keys == 0 (no keys) and potentially propagating an uninitialized/stale slot value to callers. • This is missing explicit handling for an important boundary case (zero keys), which can produce incorrect behavior downstream.
Agent prompt
## Issue description
`extractKeysAndSlot()` does not assign `*slot` when there are zero keys, which can leave the output slot value uninitialized or stale.
## Issue Context
Callers of `extractKeysAndSlot()` may rely on `*slot` being set consistently even when `num_keys == 0`.
## Fix Focus Areas
- src/db.c[3201-3203]
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools
Benchmark PR from agentic-review-benchmarks#3