Skip to content

Fix out-of-bounds access in Levenshtein edit distance #15

Merged
jakob-schuster merged 2 commits into
mritchielab:mainfrom
yinshiyi:bug-fix/C-m]-out-of-bounds
Dec 22, 2025
Merged

Fix out-of-bounds access in Levenshtein edit distance #15
jakob-schuster merged 2 commits into
mritchielab:mainfrom
yinshiyi:bug-fix/C-m]-out-of-bounds

Conversation

@yinshiyi

@yinshiyi yinshiyi commented Dec 17, 2025

Copy link
Copy Markdown
Contributor

Fix out-of-bounds access in Levenshtein edit distance by using vector C of size m rather than array. (Vectors have certain extra memory overhead and allow for easier resizing or bounds checking).

Prev C[m] array size is m (0...m-1)
in the loop, C[lact] when lact == m or C[i] when lact == m, will trigger out of bound value leads to oscillation between 2 stable outcome due to neg value < threshold

Example debugging trace data before bug fix
Barcode size = 15, pos 812 trigger a false match due to C[m] out of bound (~50% as neg value) < threshold

pos=808, lact=10, m=14, C[lact]=2, threshold=2, C[m]=-9701813
pos=809, lact=11, m=14, C[lact]=2, threshold=2, C[m]=-9701813
pos=810, lact=12, m=14, C[lact]=2, threshold=2, C[m]=-9701813
pos=811, lact=13, m=14, C[lact]=2, threshold=2, C[m]=-9701813
pos=812, lact=14, m=14, C[lact]=-9701812, threshold=2, C[m]=-9701812
pos=813, lact=14, m=14, C[lact]=3, threshold=2, C[m]=3
pos=814, lact=2, m=14, C[lact]=3, threshold=2, C[m]=3
pos=815, lact=2, m=14, C[lact]=2, threshold=2, C[m]=3
pos=816, lact=3, m=14, C[lact]=2, threshold=2, C[m]=3

The other 50%, the out of bound report a large positive value and pos 812 is not matched.

pos=809, lact=11, m=14, C[lact]=2, threshold=2, C[m]=1246254667
pos=810, lact=12, m=14, C[lact]=2, threshold=2, C[m]=1246254667
pos=811, lact=13, m=14, C[lact]=2, threshold=2, C[m]=1246254667
pos=812, lact=14, m=14, C[lact]=3, threshold=2, C[m]=3
pos=813, lact=3, m=14, C[lact]=3, threshold=2, C[m]=3
pos=814, lact=2, m=14, C[lact]=3, threshold=2, C[m]=3
pos=815, lact=2, m=14, C[lact]=2, threshold=2, C[m]=3

After bug fix, C[m] out of bound issue is resolved

pos=809, lact=11, m=14, C[lact]=2, threshold=2, C[m]=3
pos=810, lact=12, m=14, C[lact]=2, threshold=2, C[m]=3
pos=811, lact=13, m=14, C[lact]=2, threshold=2, C[m]=3
pos=812, lact=14, m=14, C[lact]=3, threshold=2, C[m]=3
pos=813, lact=3, m=14, C[lact]=3, threshold=2, C[m]=3
pos=814, lact=2, m=14, C[lact]=3, threshold=2, C[m]=3
pos=815, lact=2, m=14, C[lact]=2, threshold=2, C[m]=3

@yinshiyi

Copy link
Copy Markdown
Contributor Author

This bug fix works well for now.
Future work could include further improving lact update loop safely, to avoid all potential out-of-bounds accesses.

while (C[lact] > threshold) {
lact--;
}
if (lact == m) {
if (firstMatchPos == -1 || pos < firstMatchPos) {
firstMatchPos = pos; // always pick earliest
}
} else {
lact++;
}

@yinshiyi yinshiyi changed the title Fix out-of-bounds access in Ukkonen edit distance Fix out-of-bounds access in Levenshtein edit distance Dec 17, 2025
…f size m rather than array. (Vectors have certain extra memory overhead and allow for easier resizing or bounds checking).

Prev C[m] array size is m (0...m-1)
in the loop, C[lact] when lact == m or C[i] when lact == m, will trigger out of bound value leads to oscillation between 2 stable outcome due to neg value < threshold
@yinshiyi yinshiyi force-pushed the bug-fix/C-m]-out-of-bounds branch from 7f68b8d to 1c6ad87 Compare December 17, 2025 23:24
@yinshiyi

Copy link
Copy Markdown
Contributor Author

@jakob-schuster , could you please let me know your thoughts when you have time? thanks!

@jakob-schuster jakob-schuster merged commit 1c6ad87 into mritchielab:main Dec 22, 2025
1 check passed
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.

2 participants