diff --git a/CHANGELOG.rst b/CHANGELOG.rst index aeae1f8d..a90ebab8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,12 @@ Changelog --------- +[3.6.0] - 2023-12-28 +^^^^^^^^^^^^^^^^^^^^ +Fixed +~~~~~ +- fix overflow error on systems with ``sizeof(size_t) < 8`` + [3.6.0] - 2023-12-26 ^^^^^^^^^^^^^^^^^^^^ Fixed diff --git a/src/rapidfuzz/cpp_common.pxd b/src/rapidfuzz/cpp_common.pxd index ae1bbf79..6d46fcf7 100644 --- a/src/rapidfuzz/cpp_common.pxd +++ b/src/rapidfuzz/cpp_common.pxd @@ -4,7 +4,7 @@ from cpython.object cimport PyObject from cpython.pycapsule cimport PyCapsule_GetPointer, PyCapsule_IsValid, PyCapsule_New from libc.stddef cimport wchar_t -from libc.stdint cimport int64_t, uint64_t, SIZE_MAX +from libc.stdint cimport int64_t, uint64_t, SIZE_MAX, UINT64_MAX from libc.stdlib cimport free, malloc from libcpp cimport bool from libcpp.utility cimport move, pair @@ -352,7 +352,6 @@ cdef inline int64_t get_score_cutoff_i64(score_cutoff, int64_t worst_score, int6 cdef int64_t c_score_cutoff = worst_score if score_cutoff is not None: - c_score_cutoff = score_cutoff if optimal_score > worst_score: # e.g. 0.0 - 100.0 if c_score_cutoff < worst_score or c_score_cutoff > optimal_score: @@ -365,10 +364,13 @@ cdef inline int64_t get_score_cutoff_i64(score_cutoff, int64_t worst_score, int6 return c_score_cutoff cdef inline size_t get_score_cutoff_size_t(score_cutoff, size_t worst_score, size_t optimal_score) except *: - cdef size_t c_score_cutoff = worst_score + cdef uint64_t c_score_cutoff = worst_score if score_cutoff is not None: c_score_cutoff = score_cutoff + if c_score_cutoff > SIZE_MAX: + c_score_cutoff= SIZE_MAX + if optimal_score > worst_score: # e.g. 0.0 - 100.0 if c_score_cutoff < worst_score or c_score_cutoff > optimal_score: @@ -378,7 +380,7 @@ cdef inline size_t get_score_cutoff_size_t(score_cutoff, size_t worst_score, siz if c_score_cutoff > worst_score or c_score_cutoff < optimal_score: raise TypeError(f"score_cutoff has to be in the range of {optimal_score} - {worst_score}") - return c_score_cutoff + return c_score_cutoff cdef inline void preprocess_strings(s1, s2, processor, RF_StringWrapper* s1_proc, RF_StringWrapper* s2_proc) except *: cdef RF_Preprocessor* preprocess_context = NULL diff --git a/tests/distance/test_Levenshtein.py b/tests/distance/test_Levenshtein.py index 2e2ab784..3f95a7b0 100644 --- a/tests/distance/test_Levenshtein.py +++ b/tests/distance/test_Levenshtein.py @@ -29,6 +29,13 @@ def test_empty_string(): assert Levenshtein.distance("", "", weights=(3, 7, 5)) == 0 +def test_score_cutoff_overflow(): + """ + when score_cutoff was out of bounds for size_t we had an overflow error + """ + assert Levenshtein.distance("", "") == 0 + assert Levenshtein.distance("", "", score_cutoff=2**63) == 0 + def test_cross_type_matching(): """ strings should always be interpreted in the same way