bufferlist a;
a.append("A");
bufferlist ab;
ab.append("AB");
a >= ab failed, throwing an instance of 'ceph::buffer::end_of_buffer'
because it tried to access a[1]. All comparison operators should be
tested using a lexicographic sort like strcmp or memcmp (-1, 0, 1).
In the meantime, the missing test is added:
if (l.length() == p && r.length() > p) return false;
A set of unit tests demonstrating the problem and covering all comparison
operators are added to show that the proposed fix works as expected.
http://tracker.ceph.com/issues/4157 refs #4157
Signed-off-by: Loic Dachary <loic@dachary.org>
for (unsigned p = 0; ; p++) {
if (l.length() > p && r.length() == p) return true;
if (r.length() == p && l.length() == p) return true;
+ if (l.length() == p && r.length() > p) return false;
if (l[p] > r[p]) return true;
if (l[p] < r[p]) return false;
}
}
}
+TEST(BufferList, compare) {
+ bufferlist a;
+ a.append("A");
+ bufferlist ab;
+ ab.append("AB");
+ bufferlist ac;
+ ac.append("AC");
+ //
+ // bool operator>(bufferlist& l, bufferlist& r)
+ //
+ ASSERT_FALSE(a > ab);
+ ASSERT_TRUE(ab > a);
+ ASSERT_TRUE(ac > ab);
+ ASSERT_FALSE(ab > ac);
+ ASSERT_FALSE(ab > ab);
+ //
+ // bool operator>=(bufferlist& l, bufferlist& r)
+ //
+ ASSERT_FALSE(a >= ab);
+ ASSERT_TRUE(ab >= a);
+ ASSERT_TRUE(ac >= ab);
+ ASSERT_FALSE(ab >= ac);
+ ASSERT_TRUE(ab >= ab);
+ //
+ // bool operator<(bufferlist& l, bufferlist& r)
+ //
+ ASSERT_TRUE(a < ab);
+ ASSERT_FALSE(ab < a);
+ ASSERT_FALSE(ac < ab);
+ ASSERT_TRUE(ab < ac);
+ ASSERT_FALSE(ab < ab);
+ //
+ // bool operator<=(bufferlist& l, bufferlist& r)
+ //
+ ASSERT_TRUE(a <= ab);
+ ASSERT_FALSE(ab <= a);
+ ASSERT_FALSE(ac <= ab);
+ ASSERT_TRUE(ab <= ac);
+ ASSERT_TRUE(ab <= ab);
+ //
+ // bool operator==(bufferlist &l, bufferlist &r)
+ //
+ ASSERT_FALSE(a == ab);
+ ASSERT_FALSE(ac == ab);
+ ASSERT_TRUE(ab == ab);
+}
+
TEST(BufferList, EmptyAppend) {
bufferlist bl;
bufferptr ptr;