ldb index: Fix truncation key length calculation
authorGary Lockyer <gary@catalyst.net.nz>
Mon, 12 Mar 2018 19:10:54 +0000 (08:10 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 6 Apr 2018 00:08:44 +0000 (02:08 +0200)
Signed-off-by: Gary Lockyer <gary@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/ldb/ldb_tdb/ldb_index.c
lib/ldb/tests/python/index.py

index 076db10f2ddd72567146fcfe50156b229838399d..ed28c4f642ff8e12a3714c9b7712b8ea98958166 100644 (file)
@@ -848,6 +848,19 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
        unsigned indx_len = 0;
        unsigned frmt_len = 0;
 
+       if (max_key_length < 4) {
+               ldb_asprintf_errstring(
+                       ldb,
+                       __location__ ": max_key_length of (%u) < 4",
+                       max_key_length);
+               return NULL;
+       }
+       /*
+        * ltdb_key_dn() makes something 4 bytes longer, it adds a leading
+        * "DN=" and a trailing string terninator
+        */
+       max_key_length -= 4;
+
        if (attr[0] == '@') {
                attr_for_dn = attr;
                v = *value;
@@ -911,12 +924,13 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
        if (should_b64_encode) {
                unsigned vstr_len = 0;
                char *vstr = ldb_base64_encode(ldb, (char *)v.data, v.length);
+               unsigned num_separators = 3;
                if (!vstr) {
                        talloc_free(attr_folded);
                        return NULL;
                }
                vstr_len = strlen(vstr);
-               key_len = 3 + indx_len + attr_len + vstr_len;
+               key_len = num_separators + indx_len + attr_len + vstr_len;
                if (key_len > max_key_length) {
                        unsigned excess = key_len - max_key_length;
                        frmt_len = vstr_len - excess;
@@ -943,7 +957,8 @@ static struct ldb_dn *ltdb_index_key(struct ldb_context *ldb,
                }
                talloc_free(vstr);
        } else {
-               key_len = 2 + indx_len + attr_len + (int)v.length;
+               unsigned num_separators = 2;
+               key_len = num_separators + indx_len + attr_len + (int)v.length;
                if (key_len > max_key_length) {
                        unsigned excess = key_len - max_key_length;
                        frmt_len = v.length - excess;
index e9eaaf059e198181d470becdbb6a08004c5b4a9e..1d66ee930d10d6f6402cfc0ee7c25b2e49ada02f 100755 (executable)
@@ -113,11 +113,14 @@ class MaxIndexKeyLengthTests(LdbBaseTest):
         super(MaxIndexKeyLengthTests, self).setUp()
         self.testdir = tempdir()
         self.filename = os.path.join(self.testdir, "key_len_test.ldb")
-        # Note that the maximum key length is set to 50
+        # Note that the maximum key length is set to 54
+        # This accounts for the 4 bytes added by the dn formatting
+        # a leading dn=, and a trailing zero terminator
+        #
         self.l = ldb.Ldb(self.url(),
                          options=[
                              "modules:rdn_name",
-                             "max_key_len_for_self_test:50"])
+                             "max_key_len_for_self_test:54"])
         self.l.add({"dn": "@ATTRIBUTES",
                     "uniqueThing": "UNIQUE_INDEX"})
         self.l.add({"dn": "@INDEXLIST",