Skip to content

Fix the memory leak in the VM_GetCommandKeysWithFlags function#3088

Merged
enjoy-binbin merged 6 commits into
valkey-io:unstablefrom
arshidkv12:mem-leak-module-1
Jan 22, 2026
Merged

Fix the memory leak in the VM_GetCommandKeysWithFlags function#3088
enjoy-binbin merged 6 commits into
valkey-io:unstablefrom
arshidkv12:mem-leak-module-1

Conversation

@arshidkv12

@arshidkv12 arshidkv12 commented Jan 21, 2026

Copy link
Copy Markdown
Contributor

Memory leak in the VM_GetCommandKeysWithFlags function when MAX_KEYS_BUFFER is reached.
We will malloc the memory so we should always free the getKeysResult.

    /* Resize if necessary */
    if (numkeys > result->size) {
        if (result->keys != result->keysbuf) {
            /* We're not using a static buffer, just (re)alloc */
            result->keys = zrealloc(result->keys, numkeys * sizeof(keyReference));
        } else {
            /* We are using a static buffer, copy its contents */
            result->keys = zmalloc(numkeys * sizeof(keyReference));
            if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference));
        }
        result->size = numkeys;
    }

Closes #3087.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Comment thread tests/unit/moduleapi/getkeys.tcl Outdated
Comment thread tests/unit/moduleapi/getkeys.tcl Outdated
Comment thread tests/unit/moduleapi/getkeys.tcl Outdated
arshidkv12 and others added 3 commits January 21, 2026 18:58
Co-authored-by: Binbin <binloveplay1314@qq.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
@codecov

codecov Bot commented Jan 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 74.27%. Comparing base (0b1f99d) to head (b12cae3).
⚠️ Report is 10 commits behind head on unstable.

Files with missing lines Patch % Lines
src/module.c 0.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #3088      +/-   ##
============================================
- Coverage     74.33%   74.27%   -0.06%     
============================================
  Files           129      129              
  Lines         71009    71013       +4     
============================================
- Hits          52784    52746      -38     
- Misses        18225    18267      +42     
Files with missing lines Coverage Δ
src/module.c 26.50% <0.00%> (-0.01%) ⬇️

... and 28 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Comment thread tests/unit/moduleapi/getkeys.tcl Outdated
Signed-off-by: Binbin <binloveplay1314@qq.com>

@enjoy-binbin enjoy-binbin left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@enjoy-binbin enjoy-binbin moved this to To be backported in Valkey 7.2 Jan 22, 2026
@enjoy-binbin enjoy-binbin moved this to To be backported in Valkey 8.0 Jan 22, 2026
@enjoy-binbin enjoy-binbin moved this to To be backported in Valkey 8.1 Jan 22, 2026
@enjoy-binbin enjoy-binbin moved this to To be backported in Valkey 9.0 Jan 22, 2026
@arshidkv12

Copy link
Copy Markdown
Contributor Author

Thanks for the review!

@enjoy-binbin enjoy-binbin added the run-extra-tests Run extra tests on this PR (Runs all tests from daily except valgrind and RESP) label Jan 22, 2026
@arshidkv12

Copy link
Copy Markdown
Contributor Author

MPTCP is not supported on mac OS. @enjoy-binbin

@enjoy-binbin

enjoy-binbin commented Jan 22, 2026

Copy link
Copy Markdown
Member

MPTCP is not supported on mac OS. @enjoy-binbin

no worry, it was fixed in the unstable branch.

@enjoy-binbin enjoy-binbin merged commit 2e2eb41 into valkey-io:unstable Jan 22, 2026
64 of 65 checks passed
@arshidkv12

Copy link
Copy Markdown
Contributor Author

Thank you

@github-actions github-actions Bot removed the run-extra-tests Run extra tests on this PR (Runs all tests from daily except valgrind and RESP) label Jan 22, 2026
arshidkv12 added a commit to arshidkv12/valkey that referenced this pull request Jan 23, 2026
…y-io#3088)

Memory leak in the VM_GetCommandKeysWithFlags function when
MAX_KEYS_BUFFER is reached.
We will malloc the memory so we should always free the getKeysResult.
```
    /* Resize if necessary */
    if (numkeys > result->size) {
        if (result->keys != result->keysbuf) {
            /* We're not using a static buffer, just (re)alloc */
            result->keys = zrealloc(result->keys, numkeys * sizeof(keyReference));
        } else {
            /* We are using a static buffer, copy its contents */
            result->keys = zmalloc(numkeys * sizeof(keyReference));
            if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference));
        }
        result->size = numkeys;
    }
```

Closes valkey-io#3087.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
PingXie added a commit to PingXie/valkey that referenced this pull request Jan 26, 2026
Issue: PR valkey-io#3088 matched Redis #14243 perfectly on both files (patch-id),
but was being filtered out by line percentage check (7.7% < 50%).

Fixes:
1. Bypass line percentage filter for patch-id (exact) matches
2. Sort matches by same_files_count first, then similarity
   - PRs matching multiple files ranked higher
   - Ensures #14243 (2-file match) appears before single-file matches

Result: PR valkey-io#3088 now correctly shows #14243 as primary match
Signed-off-by: Ping Xie <pingxie@outlook.com>
PingXie added a commit to PingXie/valkey that referenced this pull request Jan 27, 2026
Issue: PR valkey-io#1 falsely matched Redis #13157 due to patch-id collision.
- Valkey PR valkey-io#1: 2-file test PR touching dict.h and t_zset.c
- Redis PR #13157: 36-file license change PR
- Both happened to have same patch-id (efdd4d9b5640) for t_zset.c

Fix: Add file count ratio check for patch-id matches.
- If file counts differ by >3x, treat as collision (suppress match)
- Example: 2 files vs 36 files = 18x ratio -> filtered out
- Example: 2 files vs 2 files = 1x ratio -> kept

Result:
- PR valkey-io#1 now passes (no false positive from license change PR)
- PR valkey-io#3088 still correctly detects #14243 (2 files vs 2 files)

Signed-off-by: Ping Xie <pingxie@outlook.com>
PingXie added a commit to PingXie/valkey that referenced this pull request Jan 27, 2026
Implements line-by-line comparison of actual diff content after initial
fingerprint matching to validate matches are truly similar.

Features:
- deep_compare_diffs(): Compares normalized diffs using Jaccard + sequence similarity
- Validates top candidates only (up to 2x report limit) to minimize API calls
- Adaptive thresholds: 50% for patch-id matches, 70% for simhash matches
- Graceful fallback: accepts fingerprint match if deep comparison fails

Benefits:
- Filters patch-id hash collisions (different changes, same hash)
- Validates simhash matches are semantically similar
- PR valkey-io#3088: correctly detects #14243, rejects 40+ collision false positives
- PR valkey-io#1: still passes (no false matches)

Performance:
- Before: checked every match (~60+ API calls for PR valkey-io#3088)
- After: checks top 10 candidates (~10 API calls)
- Speedup: 9s vs 60+s for PR valkey-io#3088

Signed-off-by: Ping Xie <pingxie@outlook.com>
PingXie added a commit to PingXie/valkey that referenced this pull request Jan 27, 2026
Issue: PR valkey-io#3105 was passing even though it's a subset of Redis #14435.
- Valkey: Adds IFNE option (132 lines, 7 files)
- Redis: Adds IFEQ/IFNE/IFNEQ + xxhash + digest (9843 lines, 18 files)
- Jaccard similarity only 20% due to size difference
- But 90-100% of Valkey tokens exist in Redis (subset relationship)

Fix: Check subset ratio in addition to Jaccard similarity.
- Subset ratio = |Valkey ∩ Redis| / |Valkey|
- Detects when smaller PR cherry-picks from larger PR
- Final similarity = max(weighted_jaccard, subset_ratio)

Per-file analysis of PR valkey-io#3105 vs #14435:
- src/commands.def: 92.9% subset ratio
- src/commands/set.json: 93.8% subset ratio
- src/t_string.c: 95.5% subset ratio
- tests/unit/type/string.tcl: 100% subset ratio

Result:
- PR valkey-io#3105 now correctly detects Redis #14435 match
- PR valkey-io#3088 still works (detects #14243)
- PR valkey-io#1 still passes (no false positives)

Signed-off-by: Ping Xie <pingxie@outlook.com>
PingXie added a commit to PingXie/valkey that referenced this pull request Jan 27, 2026
Remove patch-id completely - it was causing false positives from:
- Hash collisions on small changes
- Trivial whitespace/formatting fixes
- Unrelated changes to same code

New approach:
- Layer 1: Liberal candidate generation (SimHash > 0.70, local DB lookup)
- Layer 2: Deep content validation (Jaccard+subset > 0.75, requires API)

Benefits:
- Simpler logic: Two clear functions, no special cases
- Fewer false positives: No patch-id collisions
- Same API call count: ~6-11 calls per Valkey PR
- Better accuracy: True copies still detected, false positives filtered

Changes:
- common.py: Removed compute_patch_id(), compute_similarity()
- common.py: Added compute_simhash_similarity(), updated thresholds
- check_provenance.py: Replaced complex find_matches() with layer1_find_candidates() + layer2_validate_candidate()
- refresh_redis_prs.py: Removed patch-id computation
- bootstrap_redis_commits.py: Removed patch-id computation
- Rebuilt database without patch-id fields
- Updated all tests to remove patch-id references

Validation:
- All 30 tests pass
- PR valkey-io#3088 correctly detected (0.891 similarity with #14243)
- PR #14268 patch-id collision false positive eliminated

Signed-off-by: Ping Xie <pingxie@outlook.com>
@zuiderkwast zuiderkwast removed the status in Valkey 9.0 Jan 28, 2026
roshkhatri pushed a commit to roshkhatri/valkey that referenced this pull request Jan 29, 2026
…y-io#3088)

Memory leak in the VM_GetCommandKeysWithFlags function when
MAX_KEYS_BUFFER is reached.
We will malloc the memory so we should always free the getKeysResult.
```
    /* Resize if necessary */
    if (numkeys > result->size) {
        if (result->keys != result->keysbuf) {
            /* We're not using a static buffer, just (re)alloc */
            result->keys = zrealloc(result->keys, numkeys * sizeof(keyReference));
        } else {
            /* We are using a static buffer, copy its contents */
            result->keys = zmalloc(numkeys * sizeof(keyReference));
            if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference));
        }
        result->size = numkeys;
    }
```

Closes valkey-io#3087.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
roshkhatri pushed a commit to roshkhatri/valkey that referenced this pull request Jan 29, 2026
…y-io#3088)

Memory leak in the VM_GetCommandKeysWithFlags function when
MAX_KEYS_BUFFER is reached.
We will malloc the memory so we should always free the getKeysResult.
```
    /* Resize if necessary */
    if (numkeys > result->size) {
        if (result->keys != result->keysbuf) {
            /* We're not using a static buffer, just (re)alloc */
            result->keys = zrealloc(result->keys, numkeys * sizeof(keyReference));
        } else {
            /* We are using a static buffer, copy its contents */
            result->keys = zmalloc(numkeys * sizeof(keyReference));
            if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference));
        }
        result->size = numkeys;
    }
```

Closes valkey-io#3087.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
Signed-off-by: Roshan Khatri <rvkhatri@amazon.com>
@roshkhatri roshkhatri moved this from To be backported to 8.1.6 in Valkey 8.1 Jan 29, 2026
roshkhatri pushed a commit to roshkhatri/valkey that referenced this pull request Jan 29, 2026
…y-io#3088)

Memory leak in the VM_GetCommandKeysWithFlags function when
MAX_KEYS_BUFFER is reached.
We will malloc the memory so we should always free the getKeysResult.
```
    /* Resize if necessary */
    if (numkeys > result->size) {
        if (result->keys != result->keysbuf) {
            /* We're not using a static buffer, just (re)alloc */
            result->keys = zrealloc(result->keys, numkeys * sizeof(keyReference));
        } else {
            /* We are using a static buffer, copy its contents */
            result->keys = zmalloc(numkeys * sizeof(keyReference));
            if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference));
        }
        result->size = numkeys;
    }
```

Closes valkey-io#3087.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
Signed-off-by: Roshan Khatri <rvkhatri@amazon.com>
roshkhatri pushed a commit to roshkhatri/valkey that referenced this pull request Jan 29, 2026
…y-io#3088)

Memory leak in the VM_GetCommandKeysWithFlags function when
MAX_KEYS_BUFFER is reached.
We will malloc the memory so we should always free the getKeysResult.
```
    /* Resize if necessary */
    if (numkeys > result->size) {
        if (result->keys != result->keysbuf) {
            /* We're not using a static buffer, just (re)alloc */
            result->keys = zrealloc(result->keys, numkeys * sizeof(keyReference));
        } else {
            /* We are using a static buffer, copy its contents */
            result->keys = zmalloc(numkeys * sizeof(keyReference));
            if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference));
        }
        result->size = numkeys;
    }
```

Closes valkey-io#3087.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
roshkhatri pushed a commit to roshkhatri/valkey that referenced this pull request Jan 29, 2026
…y-io#3088)

Memory leak in the VM_GetCommandKeysWithFlags function when
MAX_KEYS_BUFFER is reached.
We will malloc the memory so we should always free the getKeysResult.
```
    /* Resize if necessary */
    if (numkeys > result->size) {
        if (result->keys != result->keysbuf) {
            /* We're not using a static buffer, just (re)alloc */
            result->keys = zrealloc(result->keys, numkeys * sizeof(keyReference));
        } else {
            /* We are using a static buffer, copy its contents */
            result->keys = zmalloc(numkeys * sizeof(keyReference));
            if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference));
        }
        result->size = numkeys;
    }
```

Closes valkey-io#3087.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
Signed-off-by: Roshan Khatri <rvkhatri@amazon.com>
roshkhatri pushed a commit to roshkhatri/valkey that referenced this pull request Jan 30, 2026
…y-io#3088)

Memory leak in the VM_GetCommandKeysWithFlags function when
MAX_KEYS_BUFFER is reached.
We will malloc the memory so we should always free the getKeysResult.
```
    /* Resize if necessary */
    if (numkeys > result->size) {
        if (result->keys != result->keysbuf) {
            /* We're not using a static buffer, just (re)alloc */
            result->keys = zrealloc(result->keys, numkeys * sizeof(keyReference));
        } else {
            /* We are using a static buffer, copy its contents */
            result->keys = zmalloc(numkeys * sizeof(keyReference));
            if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference));
        }
        result->size = numkeys;
    }
```

Closes valkey-io#3087.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
Signed-off-by: Roshan Khatri <rvkhatri@amazon.com>
@roshkhatri roshkhatri moved this from To be backported to 8.0.7 in Valkey 8.0 Jan 30, 2026
@zuiderkwast zuiderkwast removed this from Valkey 8.1 Jan 30, 2026
@zuiderkwast zuiderkwast removed this from Valkey 9.0 Jan 30, 2026
@zuiderkwast zuiderkwast removed this from Valkey 8.0 Jan 30, 2026
@zuiderkwast zuiderkwast removed this from Valkey 7.2 Jan 30, 2026
zuiderkwast added a commit to zuiderkwast/valkey that referenced this pull request Jan 30, 2026
@zuiderkwast zuiderkwast mentioned this pull request Jan 30, 2026
zuiderkwast added a commit to zuiderkwast/valkey that referenced this pull request Jan 30, 2026
valkey-io#3088)"

This reverts commit 2e2eb41.

Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
zuiderkwast added a commit that referenced this pull request Jan 30, 2026
Reverts "Fix the memory leak in the VM_GetCommandKeysWithFlags function
(#3088)"

This reverts commit 2e2eb41.

Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
roshkhatri added a commit to roshkhatri/valkey that referenced this pull request Jan 30, 2026
valkey-io#3088)"

This reverts commit 7b88723.

Signed-off-by: Roshan Khatri <rvkhatri@amazon.com>
roshkhatri added a commit to roshkhatri/valkey that referenced this pull request Jan 30, 2026
valkey-io#3088)"

This reverts commit 457d032.

Signed-off-by: Roshan Khatri <rvkhatri@amazon.com>
immangat pushed a commit to immangat/valkey that referenced this pull request Feb 1, 2026
Reverts "Fix the memory leak in the VM_GetCommandKeysWithFlags function
(valkey-io#3088)"

This reverts commit 2e2eb41.

Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
harrylin98 pushed a commit to harrylin98/valkey_forked that referenced this pull request Feb 19, 2026
…y-io#3088)

Memory leak in the VM_GetCommandKeysWithFlags function when
MAX_KEYS_BUFFER is reached.
We will malloc the memory so we should always free the getKeysResult.
```
    /* Resize if necessary */
    if (numkeys > result->size) {
        if (result->keys != result->keysbuf) {
            /* We're not using a static buffer, just (re)alloc */
            result->keys = zrealloc(result->keys, numkeys * sizeof(keyReference));
        } else {
            /* We are using a static buffer, copy its contents */
            result->keys = zmalloc(numkeys * sizeof(keyReference));
            if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference));
        }
        result->size = numkeys;
    }
```

Closes valkey-io#3087.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
harrylin98 pushed a commit to harrylin98/valkey_forked that referenced this pull request Feb 19, 2026
Reverts "Fix the memory leak in the VM_GetCommandKeysWithFlags function
(valkey-io#3088)"

This reverts commit 2e2eb41.

Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
hpatro pushed a commit to hpatro/valkey that referenced this pull request Mar 5, 2026
…y-io#3088)

Memory leak in the VM_GetCommandKeysWithFlags function when
MAX_KEYS_BUFFER is reached.
We will malloc the memory so we should always free the getKeysResult.
```
    /* Resize if necessary */
    if (numkeys > result->size) {
        if (result->keys != result->keysbuf) {
            /* We're not using a static buffer, just (re)alloc */
            result->keys = zrealloc(result->keys, numkeys * sizeof(keyReference));
        } else {
            /* We are using a static buffer, copy its contents */
            result->keys = zmalloc(numkeys * sizeof(keyReference));
            if (result->numkeys) memcpy(result->keys, result->keysbuf, result->numkeys * sizeof(keyReference));
        }
        result->size = numkeys;
    }
```

Closes valkey-io#3087.

Signed-off-by: arshidkv12 <arshidkv12@gmail.com>
Signed-off-by: Arshid <arshidkv12@gmail.com>
Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Binbin <binloveplay1314@qq.com>
Signed-off-by: Harkrishn Patro <bunty.hari@gmail.com>
hpatro pushed a commit to hpatro/valkey that referenced this pull request Mar 5, 2026
Reverts "Fix the memory leak in the VM_GetCommandKeysWithFlags function
(valkey-io#3088)"

This reverts commit 2e2eb41.

Signed-off-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
Signed-off-by: Harkrishn Patro <bunty.hari@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]Memory leak in the VM_GetCommandKeysWithFlags function

4 participants