diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2010-05-26 17:19:31 +0200 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2010-05-31 12:44:55 +0200 |
commit | 2bdda6ae27dc4f3705af2a68f326f311bc219049 (patch) | |
tree | 90ff5c55a00326d835586c040c2d645e0c74f97f | |
parent | 6aff1e8988c2c673afab3b97c3a1109f62ec2ba8 (diff) |
lcs: fixed out-of-bounds array access (MBC #1007)mbc1007_pohly
Found by valgrind: the cost function is called with indices just
outside the array, causing it to read unitialized (and potentially
unavailable) memory.
Calling it like this is intentional, as the original LCS algorithm
works like that. The cost function has to map access outside of the
array to the cost at the boundaries. It also has to handle empty
arrays.
-rw-r--r-- | src/syncevo/lcs.h | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/src/syncevo/lcs.h b/src/syncevo/lcs.h index 084b849a..d7b02451 100644 --- a/src/syncevo/lcs.h +++ b/src/syncevo/lcs.h @@ -75,7 +75,21 @@ public: typedef typename T::value_type::first_type F; typedef typename T::value_type::second_type C; - static C cost(const T &a, ssize_t start, size_t end) { return a[end].second - (start == -1 ? 0 : a[start].second); } + /** + * @param a container holding sequence of items as passed to lcs() + * @param start index of first item in the gap, may be -1 + * @param end index of the last item in the gap, may be one beyond end of sequence, always >= start + * @return cost 0 for start == end, > 0 for start < end + */ + static C cost(const T &a, ssize_t start, size_t end) { + return a.empty() ? 0 : + ((end >= a.size() ? a[a.size() - 1].second : a[end].second) - + (start < 0 ? a[0].second : a[start].second)); + } + /** + * @param index valid index (>= 0, < a.size()) + * @return entry at index + */ static const F &entry_at(const T &a, size_t index) { return a[index].first; } }; |