]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
lib/generic/pack: switch to NULL on empty pack iterator
authorMarek Vavruša <mvavrusa@cloudflare.com>
Fri, 20 Apr 2018 03:15:19 +0000 (20:15 -0700)
committerVladimír Čunát <vladimir.cunat@nic.cz>
Mon, 18 Jun 2018 09:50:45 +0000 (11:50 +0200)
It's probably slightly safer to use NULL than end-array pointer,
so let's use it in this case.  Significantly adapted by Vlada
from original Marek's change, after master fixed the corruption.

lib/generic/pack.h
tests/test_pack.c

index 52722c9f349476f0f5988a02df227d81950540f2..dc7a97591ce20a5d67f1d8a9728957af3045edd1 100644 (file)
@@ -102,17 +102,17 @@ typedef array_t(uint8_t) pack_t;
  *   for (uint8_t *it = pack_head(pack); it != pack_tail(pack); it = pack_obj_next(it))
  */
 #define pack_head(pack) \
-       (&(pack).at[0])
+       ((pack).len > 0 ? &((pack).at[0]) : NULL)
 
 /** Return pack end pointer. */
 #define pack_tail(pack) \
-       (&(pack).at[(pack).len])
+       ((pack).len > 0 ? &((pack).at[(pack).len]) : NULL)
 
 /** Return packed object length. */
 static inline pack_objlen_t pack_obj_len(uint8_t *it)
 {
        pack_objlen_t len = 0;
-       if (it)
+       if (it != NULL)
                memcpy(&len, it, sizeof(len));
        return len;
 }
@@ -120,12 +120,20 @@ static inline pack_objlen_t pack_obj_len(uint8_t *it)
 /** Return packed object value. */
 static inline uint8_t *pack_obj_val(uint8_t *it)
 {
+       if (it == NULL) {
+               assert(it);
+               return NULL;
+       }
        return it + sizeof(pack_objlen_t);
 }
 
 /** Return pointer to next packed object. */
 static inline uint8_t *pack_obj_next(uint8_t *it)
 {
+       if (it == NULL) {
+               assert(it);
+               return NULL;
+       }
        return pack_obj_val(it) + pack_obj_len(it);
 }
 
@@ -160,7 +168,7 @@ static inline int pack_obj_push(pack_t *pack, const uint8_t *obj, pack_objlen_t
                return kr_error(ENOSPC);
        }
 
-       uint8_t *endp = pack_tail(*pack);
+       uint8_t *endp = pack->at + pack->len;
        memcpy(endp, (char *)&len, sizeof(len));
        memcpy(endp + sizeof(len), obj, len);
        pack->len += packed_len;
@@ -173,7 +181,7 @@ static inline int pack_obj_push(pack_t *pack, const uint8_t *obj, pack_objlen_t
 static inline uint8_t *pack_obj_find(pack_t *pack, const uint8_t *obj, pack_objlen_t len)
 {
                if (pack == NULL || obj == NULL) {
-                       assert(false);
+                       assert(obj != NULL);
                        return NULL;
                }
                uint8_t *endp = pack_tail(*pack);
@@ -194,7 +202,7 @@ static inline uint8_t *pack_obj_find(pack_t *pack, const uint8_t *obj, pack_objl
 static inline int pack_obj_del(pack_t *pack, const uint8_t *obj, pack_objlen_t len)
 {
        if (pack == NULL || obj == NULL) {
-               assert(false);
+               assert(obj != NULL);
                return kr_error(EINVAL);
        }
        uint8_t *endp = pack_tail(*pack);
index 2e8943c1483b48c9c73579b986e9c4a9b8f2e328..a648832e5f76cab7b68a1cbc99ada30e9ab57b58 100644 (file)
@@ -27,6 +27,13 @@ static void test_pack_std(void **state)
        pack_init(pack);
        assert_int_equal(pack.len, 0);
 
+       /* Test that iterator on empty pack works */
+       assert_null(pack_head(pack));
+       assert_null(pack_tail(pack));
+       assert_null(pack_obj_find(&pack, U8(""), 1));
+       assert_int_equal(pack_obj_len(pack_head(pack)), 0);
+       assert_int_equal(pack_obj_del(&pack, U8(""), 1), -1);
+
        /* Push/delete without reservation. */
        assert_int_not_equal(pack_obj_push(&pack, U8(""), 1), 0);
        assert_int_not_equal(pack_obj_del(&pack, U8(""), 1), 0);