diff options
author | David Robillard <d@drobilla.net> | 2013-06-09 02:17:32 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2013-06-09 02:17:32 +0000 |
commit | 947b2ebaee2a4a6e5b59ec90856dd66eae63b3f2 (patch) | |
tree | ba7afbe455938637f8164ebe18925da5511b09b6 | |
parent | 2cfe8f720c1691998a22fc5923e3ec93fc6859ef (diff) | |
download | ingen-947b2ebaee2a4a6e5b59ec90856dd66eae63b3f2.tar.gz ingen-947b2ebaee2a4a6e5b59ec90856dd66eae63b3f2.tar.bz2 ingen-947b2ebaee2a4a6e5b59ec90856dd66eae63b3f2.zip |
Fix crashes when comparing variable sized Atoms.
git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@5135 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r-- | ingen/Atom.hpp | 22 |
1 files changed, 12 insertions, 10 deletions
diff --git a/ingen/Atom.hpp b/ingen/Atom.hpp index a355f840..7a3e5797 100644 --- a/ingen/Atom.hpp +++ b/ingen/Atom.hpp @@ -17,6 +17,7 @@ #ifndef INGEN_ATOM_HPP #define INGEN_ATOM_HPP +#include <algorithm> #include <cassert> #include <cstring> #include <string> @@ -89,12 +90,13 @@ public: } inline bool operator==(const Atom& other) const { - if (is_reference()) { - return !memcmp(_body.ptr, other._body.ptr, sizeof(LV2_Atom) + _atom.size); + if (_atom.type != other._atom.type || + _atom.size != other._atom.size) { + return false; } - return (_atom.type == other._atom.type && - _atom.size == other._atom.size && - _body.val == other._body.val); + return is_reference() + ? !memcmp(_body.ptr, other._body.ptr, sizeof(LV2_Atom) + _atom.size) + : _body.val == other._body.val; } inline bool operator!=(const Atom& other) const { @@ -103,11 +105,11 @@ public: inline bool operator<(const Atom& other) const { if (_atom.type == other._atom.type) { - if (is_reference()) { - return memcmp(_body.ptr, other._body.ptr, _atom.size) < 0; - } else { - return memcmp(&_body.val, &other._body.val, _atom.size) < 0; - } + const uint32_t min_size = std::min(_atom.size, other._atom.size); + const int cmp = is_reference() + ? memcmp(_body.ptr, other._body.ptr, min_size) + : memcmp(&_body.val, &other._body.val, min_size); + return cmp < 0 || (cmp == 0 && _atom.size < other._atom.size); } return type() < other.type(); } |