summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2013-06-09 02:17:32 +0000
committerDavid Robillard <d@drobilla.net>2013-06-09 02:17:32 +0000
commit947b2ebaee2a4a6e5b59ec90856dd66eae63b3f2 (patch)
treeba7afbe455938637f8164ebe18925da5511b09b6
parent2cfe8f720c1691998a22fc5923e3ec93fc6859ef (diff)
downloadingen-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.hpp22
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();
}