hash table BUGFIX invalid length when resizing dict

Refs #1045
Refs #1093
diff --git a/src/hash_table.c b/src/hash_table.c
index 5f1af01..cc6fbd0 100644
--- a/src/hash_table.c
+++ b/src/hash_table.c
@@ -130,6 +130,30 @@
     return dict_hash_multi(hash, NULL, len);
 }
 
+static ly_bool
+lydict_resize_val_eq(void *val1_p, void *val2_p, ly_bool mod, void *cb_data)
+{
+    LY_CHECK_ARG_RET(NULL, val1_p, val2_p, 0);
+
+    const char *str1 = ((struct dict_rec *)val1_p)->value;
+    const char *str2 = ((struct dict_rec *)val2_p)->value;
+
+    LY_CHECK_ERR_RET(!str1, LOGARG(NULL, val1_p), 0);
+    LY_CHECK_ERR_RET(!str2, LOGARG(NULL, val2_p), 0);
+
+    if (mod) {
+        /* used when inserting new values */
+        if (strcmp(str1, str2) == 0) {
+            return 1;
+        }
+    } else {
+        /* used when finding the original value again in the resized table */
+        return lydict_val_eq(val1_p, val2_p, mod, cb_data);
+    }
+
+    return 0;
+}
+
 API void
 lydict_remove(const struct ly_ctx *ctx, const char *value)
 {
@@ -168,7 +192,7 @@
              * free it after it is removed from hash table
              */
             val_p = match->value;
-            ret = lyht_remove(ctx->dict.hash_tab, &rec, hash);
+            ret = lyht_remove_with_resize_cb(ctx->dict.hash_tab, &rec, hash, lydict_resize_val_eq);
             free(val_p);
             LY_CHECK_ERR_GOTO(ret, LOGINT(ctx), finish);
         }
@@ -193,7 +217,7 @@
     rec.refcount = 1;
 
     LOGDBG(LY_LDGDICT, "inserting \"%s\"", rec.value);
-    ret = lyht_insert(ctx->dict.hash_tab, (void *)&rec, hash, (void **)&match);
+    ret = lyht_insert_with_resize_cb(ctx->dict.hash_tab, (void *)&rec, hash, lydict_resize_val_eq, (void **)&match);
     if (ret == LY_EEXIST) {
         match->refcount++;
         if (zerocopy) {
@@ -688,12 +712,13 @@
 }
 
 LY_ERR
-lyht_remove(struct hash_table *ht, void *val_p, uint32_t hash)
+lyht_remove_with_resize_cb(struct hash_table *ht, void *val_p, uint32_t hash, values_equal_cb resize_val_equal)
 {
     struct ht_rec *rec, *crec;
     int32_t i;
     ly_bool first_matched = 0;
     LY_ERR r, ret = LY_SUCCESS;
+    values_equal_cb old_val_equal;
 
     LY_CHECK_ERR_RET(lyht_find_first(ht, hash, &rec), LOGARG(NULL, hash), LY_ENOTFOUND); /* hash not found */
 
@@ -737,10 +762,24 @@
     if (ht->resize == 2) {
         r = (ht->used * 100) / ht->size;
         if ((r < LYHT_SHRINK_PERCENTAGE) && (ht->size > LYHT_MIN_SIZE)) {
+            if (resize_val_equal) {
+                old_val_equal = lyht_set_cb(ht, resize_val_equal);
+            }
+
             /* shrink */
             ret = lyht_resize(ht, 0);
+
+            if (resize_val_equal) {
+                lyht_set_cb(ht, old_val_equal);
+            }
         }
     }
 
     return ret;
 }
+
+LY_ERR
+lyht_remove(struct hash_table *ht, void *val_p, uint32_t hash)
+{
+    return lyht_remove_with_resize_cb(ht, val_p, hash, NULL);
+}