diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2018-06-08 15:48:40 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-08 15:48:40 -0600 |
commit | a50d45918e293defbfe145dffee8893c4f97f930 (patch) | |
tree | 5bcf7d436ced5e772cb4da5bdfd36d9088c86650 | |
parent | 71650e304a0be2851b76a2465b7eef65210db53d (diff) | |
parent | 235e58d51d27a9f8665f43050d485d3d23f7288f (diff) | |
download | numpy-a50d45918e293defbfe145dffee8893c4f97f930.tar.gz |
Merge pull request #11273 from seberg/sort-valgrind-fix
BUG: Remove invalid read in searchsorted if needle is empty
-rw-r--r-- | numpy/core/src/npysort/binsearch.c.src | 14 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 14 |
2 files changed, 26 insertions, 2 deletions
diff --git a/numpy/core/src/npysort/binsearch.c.src b/numpy/core/src/npysort/binsearch.c.src index a1a07039a..c04e197b7 100644 --- a/numpy/core/src/npysort/binsearch.c.src +++ b/numpy/core/src/npysort/binsearch.c.src @@ -43,7 +43,12 @@ binsearch_@side@_@suff@(const char *arr, const char *key, char *ret, { npy_intp min_idx = 0; npy_intp max_idx = arr_len; - @type@ last_key_val = *(const @type@ *)key; + @type@ last_key_val; + + if (key_len == 0) { + return; + } + last_key_val = *(const @type@ *)key; for (; key_len > 0; key_len--, key += key_str, ret += ret_str) { const @type@ key_val = *(const @type@ *)key; @@ -86,7 +91,12 @@ argbinsearch_@side@_@suff@(const char *arr, const char *key, { npy_intp min_idx = 0; npy_intp max_idx = arr_len; - @type@ last_key_val = *(const @type@ *)key; + @type@ last_key_val; + + if (key_len == 0) { + return 0; + } + last_key_val = *(const @type@ *)key; for (; key_len > 0; key_len--, key += key_str, ret += ret_str) { const @type@ key_val = *(const @type@ *)key; diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index 05dd2efd1..b13e48fdc 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -1997,6 +1997,13 @@ class TestMethods(object): assert_equal(b, out) b = a.searchsorted(a, 'r') assert_equal(b, out + 1) + # Test empty array, use a fresh array to get warnings in + # valgrind if access happens. + e = np.ndarray(shape=0, buffer=b'', dtype=dt) + b = e.searchsorted(a, 'l') + assert_array_equal(b, np.zeros(len(a), dtype=np.intp)) + b = a.searchsorted(e, 'l') + assert_array_equal(b, np.zeros(0, dtype=np.intp)) def test_searchsorted_unicode(self): # Test searchsorted on unicode strings. @@ -2094,6 +2101,13 @@ class TestMethods(object): assert_equal(b, out) b = a.searchsorted(a, 'r', s) assert_equal(b, out + 1) + # Test empty array, use a fresh array to get warnings in + # valgrind if access happens. + e = np.ndarray(shape=0, buffer=b'', dtype=dt) + b = e.searchsorted(a, 'l', s[:0]) + assert_array_equal(b, np.zeros(len(a), dtype=np.intp)) + b = a.searchsorted(e, 'l', s) + assert_array_equal(b, np.zeros(0, dtype=np.intp)) # Test non-contiguous sorter array a = np.array([3, 4, 1, 2, 0]) |