mirror of
https://github.com/facebookresearch/faiss.git
synced 2026-10-12 02:13:36 +00:00
faiss: fix IndexIDMap range_search crash with empty SearchParameters (#5388)
Summary: Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5388 IndexIDMap::range_search checked only if params is non-null, then unconditionally constructed IDSelectorTranslated with params->sel. When an empty SearchParameters() is passed, sel is nullptr, leading to null dereference in IDSelectorTranslated::is_member -> crash/hang. This mirrors the existing guard in search_ex which checks params && params->sel. Update range_search to same logic and pass through params when sel is null, so empty SearchParameters behaves same as no params. I also took a quick look at other search functions. They all use this pattern if they support IDSelector (some do not). Fixes https://github.com/facebookresearch/faiss/issues/5332 Reviewed By: alibeklfc Differential Revision: D110987904 fbshipit-source-id: 3d87625cfc733e9ff6c7352f13e167feceae8d76
This commit is contained in:
committed by
meta-codesync[bot]
parent
e306f3036d
commit
ed29dbb0bb
@@ -228,14 +228,14 @@ void IndexIDMapTemplate<IndexT>::range_search(
|
||||
typename IndexT::distance_t radius,
|
||||
RangeSearchResult* result,
|
||||
const SearchParameters* params) const {
|
||||
if (params) {
|
||||
if (params && params->sel) {
|
||||
SearchParameters internal_search_parameters;
|
||||
IDSelectorTranslated id_selector_translated(id_map, params->sel);
|
||||
internal_search_parameters.sel = &id_selector_translated;
|
||||
|
||||
index->range_search(n, x, radius, result, &internal_search_parameters);
|
||||
} else {
|
||||
index->range_search(n, x, radius, result);
|
||||
index->range_search(n, x, radius, result, params);
|
||||
}
|
||||
|
||||
const idx_t id_map_size = static_cast<idx_t>(id_map.size());
|
||||
|
||||
@@ -337,6 +337,32 @@ class TestSelector(unittest.TestCase):
|
||||
np.testing.assert_array_equal(Iref, Inew)
|
||||
np.testing.assert_array_almost_equal(Dref, Dnew, decimal=5)
|
||||
|
||||
def test_idmap_range_empty_params(self):
|
||||
# This test crashes without checking both params && params->sel
|
||||
# are non null in IndexIDMap::range_search().
|
||||
index = faiss.IndexIDMap(faiss.IndexFlatL2(2))
|
||||
|
||||
xb = np.array(
|
||||
[
|
||||
[0, 0],
|
||||
[1, 0],
|
||||
[0, 2],
|
||||
],
|
||||
dtype="float32",
|
||||
)
|
||||
ids = np.array([10, 20, 30], dtype="int64")
|
||||
index.add_with_ids(xb, ids)
|
||||
xq = np.array([[0, 0]], dtype="float32")
|
||||
|
||||
lims_ref, D_ref, I_ref = index.range_search(xq, 5.0)
|
||||
lims, D, I = index.range_search(
|
||||
xq, 5.0, params=faiss.SearchParameters()
|
||||
)
|
||||
|
||||
np.testing.assert_array_equal(lims_ref, lims)
|
||||
np.testing.assert_array_equal(sorted(I_ref), sorted(I))
|
||||
np.testing.assert_array_equal(sorted(D_ref), sorted(D))
|
||||
|
||||
def test_bounds(self):
|
||||
# https://github.com/facebookresearch/faiss/issues/3156
|
||||
d = 64 # dimension
|
||||
|
||||
Reference in New Issue
Block a user