[错误] 向 'get_nns_by_item' 或 'get_nns_by_vector' 传递负数作为 'n' 会导致结果不正确并发生整数溢出
作者: saitejabandaru-in创建于 2026年7月20日更新于 2026年7月20日
在使用 Python API 查询 Annoy 索引时,如果一个负整数(如 “n = -1 ”) 被传递为 “ get nns by-tem” 或 “ get nns by vector” 的 “n” 参数,则函数返回完全不正确的结果或空列表 `[] ,而不是丢出 Python 例外。
- 复制
从烦恼导入 AnnoyIndex
t = AnoyIndex(10, “角” )
i 在范围(10):
v = [如果 j == = j = o = 0 = j 范围 (10)]
t.add 项目(一,五)
t. 建设( 10)
# 预期 : [0], 但得到完全无关的项目或空列表
打印(t.get nns by item(0, -1))
打印(t.get nns by item(0,-2))根原因 :
在annoymodule.cc'中,n'被解释为已签名的`int32 t':
翻译:
int32 t项,n, search k=-1,包括 距离=0;
如果 (! PyArg ParseTupleAndKeywords(args, kwargs, "ii" -- -- ii", (char**) kwlist, & item, &n, &search k, & including stars) ) , 则使用“ kwlit” 或“ kwlit” 。
但是,在`annoylib.h'中,相应的论据是未署名的`size tn':
翻译:
空取 nns by item(S项,大小 t n, int search k,向量 <S>*QQ结果,向量 <T>*Q>*距离) constn = -1'被通过时,其签号为SIZE MAX'(例如1844744073709551615')。
这导致在 QQget all nns 中出现连锁问题:
Search k' Overflow**:search k=n * broot.size();'溢出。 由于search-k'是int',它默默地包围到一个负数。- ** 无限制搜索条件**:
(nns.size () < (signe t) search k !q.empty ())'将负数search k' 转换回SIZE MAX',导致搜索试图探索整个无限制树。 - ** " 目标结果 " **:
大小-t p=n < m?n:m;评价为m ' (因为SIZE MAX < m'是虚假的),导致所有被探索的项目被退回。 由于无界限的勘探界限,这往往产生完全随机的错误项目或`[]'。
建议的修补 在“annoymodule.cc”中添加一个参数约束检查,以确保在给 C++ 核心打电话之前“n + 0”: 翻译: 如果(n < 0) { PyErr SetString( PyExc ValueError, “n必须是非负整数” ); 还原 NULL ; {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?
内容来源: spotify/annoy