libyang BUGFIX avoid invalid parameters for memmove and memcpy
diff --git a/src/hash_table.c b/src/hash_table.c
index fecdd5c..b07c3ad 100644
--- a/src/hash_table.c
+++ b/src/hash_table.c
@@ -242,7 +242,9 @@
              */
             match->value = malloc(sizeof *match->value * (len + 1));
             LY_CHECK_ERR_RET(!match->value, LOGMEM(ctx), LY_EMEM);
-            memcpy(match->value, value, len);
+            if (len) {
+                memcpy(match->value, value, len);
+            }
             match->value[len] = '\0';
         }
     } else {
diff --git a/src/in.c b/src/in.c
index 7d9d046..359e407 100644
--- a/src/in.c
+++ b/src/in.c
@@ -356,7 +356,9 @@
         return LY_EDENIED;
     }
 
-    memcpy(buf, in->current, count);
+    if (count) {
+        memcpy(buf, in->current, count);
+    }
     in->current += count;
     return LY_SUCCESS;
 }
diff --git a/src/json.c b/src/json.c
index c5c3f32..4613d49 100644
--- a/src/json.c
+++ b/src/json.c
@@ -256,7 +256,9 @@
                 buf = ly_realloc(buf, len + offset + 1);
                 LY_CHECK_ERR_RET(!buf, LOGMEM(jsonctx->ctx), LY_EMEM);
                 size = len + offset + 1;
-                memcpy(&buf[len], in, offset);
+                if (offset) {
+                    memcpy(&buf[len], in, offset);
+                }
 
                 /* set terminating NULL byte */
                 buf[len + offset] = '\0';
diff --git a/src/out.c b/src/out.c
index 898d663..4590f26 100644
--- a/src/out.c
+++ b/src/out.c
@@ -433,7 +433,9 @@
             *out->method.mem.buf = aux;
             out->method.mem.size = out->method.mem.len + written + 1;
         }
-        memcpy(&(*out->method.mem.buf)[out->method.mem.len], msg, written);
+        if (written) {
+            memcpy(&(*out->method.mem.buf)[out->method.mem.len], msg, written);
+        }
         out->method.mem.len += written;
         (*out->method.mem.buf)[out->method.mem.len] = '\0';
         free(msg);
@@ -542,7 +544,9 @@
             out->buf_size = out->buf_len + len;
         }
 
-        memcpy(&out->buffered[out->buf_len], buf, len);
+        if (len) {
+            memcpy(&out->buffered[out->buf_len], buf, len);
+        }
         out->buf_len += len;
 
         out->printed += len;
@@ -563,7 +567,9 @@
             }
             out->method.mem.size = out->method.mem.len + len + 1;
         }
-        memcpy(&(*out->method.mem.buf)[out->method.mem.len], buf, len);
+        if (len) {
+            memcpy(&(*out->method.mem.buf)[out->method.mem.len], buf, len);
+        }
         out->method.mem.len += len;
         (*out->method.mem.buf)[out->method.mem.len] = '\0';
 
@@ -704,6 +710,8 @@
 {
     LY_ERR ret = LY_SUCCESS;
 
+    assert(count);
+
     switch (out->type) {
     case LY_OUT_MEMORY:
         /* write */
diff --git a/src/parser_json.c b/src/parser_json.c
index b0eeab0..cf8e8df 100644
--- a/src/parser_json.c
+++ b/src/parser_json.c
@@ -850,7 +850,7 @@
 {
     if (*node_p) {
         /* insert, keep first pointer correct */
-        lyd_insert_node(&parent->node, first_p, *node_p);
+        lyd_insert_node(parent ? &parent->node : NULL, first_p, *node_p);
         if (first_p) {
             if (parent) {
                 *first_p = parent->child;
diff --git a/src/plugins_types/binary.c b/src/plugins_types/binary.c
index bdb54d7..e3bd6f2 100644
--- a/src/plugins_types/binary.c
+++ b/src/plugins_types/binary.c
@@ -226,10 +226,12 @@
         if (options & LYPLG_TYPE_STORE_DYNAMIC) {
             val->data = (void *)value;
             options &= ~LYPLG_TYPE_STORE_DYNAMIC;
-        } else {
+        } else if (value_len) {
             val->data = malloc(value_len);
             LY_CHECK_ERR_GOTO(!val->data, ret = LY_EMEM, cleanup);
             memcpy(val->data, value, value_len);
+        } else {
+            val->data = NULL;
         }
 
         /* store size */
@@ -350,13 +352,15 @@
     }
 
     LYD_VALUE_GET(original, orig_val);
-    dup_val->data = malloc(orig_val->size);
-    if (!dup_val->data) {
-        lydict_remove(ctx, dup->_canonical);
-        LYPLG_TYPE_VAL_INLINE_DESTROY(dup_val);
-        return LY_EMEM;
+    if (orig_val->size) {
+        dup_val->data = malloc(orig_val->size);
+        if (!dup_val->data) {
+            lydict_remove(ctx, dup->_canonical);
+            LYPLG_TYPE_VAL_INLINE_DESTROY(dup_val);
+            return LY_EMEM;
+        }
+        memcpy(dup_val->data, orig_val->data, orig_val->size);
     }
-    memcpy(dup_val->data, orig_val->data, orig_val->size);
     dup_val->size = orig_val->size;
 
     dup->realtype = original->realtype;
diff --git a/src/schema_compile_amend.c b/src/schema_compile_amend.c
index 65d9dfa..1ea084b 100644
--- a/src/schema_compile_amend.c
+++ b/src/schema_compile_amend.c
@@ -1068,7 +1068,9 @@
         } \
         LY_ARRAY_DECREMENT(ORIG_ARRAY); \
         FREE_FUNC(ctx->ctx, &(ORIG_ARRAY)[v]); \
-        memmove(&(ORIG_ARRAY)[v], &(ORIG_ARRAY)[v + 1], (LY_ARRAY_COUNT(ORIG_ARRAY) - v) * sizeof *(ORIG_ARRAY)); \
+        if (v < LY_ARRAY_COUNT(ORIG_ARRAY)) { \
+            memmove(&(ORIG_ARRAY)[v], &(ORIG_ARRAY)[v + 1], (LY_ARRAY_COUNT(ORIG_ARRAY) - v) * sizeof *(ORIG_ARRAY)); \
+        } \
     } \
     if (!LY_ARRAY_COUNT(ORIG_ARRAY)) { \
         LY_ARRAY_FREE(ORIG_ARRAY); \
diff --git a/src/set.c b/src/set.c
index 30f00ee..8be7ad8 100644
--- a/src/set.c
+++ b/src/set.c
@@ -102,8 +102,13 @@
 
     LY_CHECK_ARG_RET(NULL, set, newset_p, LY_EINVAL);
 
-    newset = malloc(sizeof *newset);
+    newset = calloc(1, sizeof *newset);
     LY_CHECK_ERR_RET(!newset, LOGMEM(NULL), LY_EMEM);
+    if (!set->count) {
+        *newset_p = newset;
+        return LY_SUCCESS;
+    }
+
     newset->count = set->count;
     newset->size = set->count; /* optimize the size */
     newset->objs = malloc(newset->size * sizeof *(newset->objs));
diff --git a/src/xml.c b/src/xml.c
index 907058d..1294b37 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -458,7 +458,9 @@
                 buf = ly_realloc(buf, len + offset + 1);
                 LY_CHECK_ERR_RET(!buf, LOGMEM(ctx), LY_EMEM);
                 size = len + offset + 1;
-                memcpy(&buf[len], in, offset);
+                if (offset) {
+                    memcpy(&buf[len], in, offset);
+                }
 
                 /* set terminating NULL byte */
                 buf[len + offset] = '\0';
diff --git a/src/xpath.c b/src/xpath.c
index ea1cdfc..a5651fc 100644
--- a/src/xpath.c
+++ b/src/xpath.c
@@ -805,9 +805,13 @@
         }
     } else if (set->type == LYXP_SET_NODE_SET) {
         ret->type = set->type;
-        ret->val.nodes = malloc(set->used * sizeof *ret->val.nodes);
-        LY_CHECK_ERR_RET(!ret->val.nodes, LOGMEM(set->ctx); free(ret), NULL);
-        memcpy(ret->val.nodes, set->val.nodes, set->used * sizeof *ret->val.nodes);
+        if (set->used) {
+            ret->val.nodes = malloc(set->used * sizeof *ret->val.nodes);
+            LY_CHECK_ERR_RET(!ret->val.nodes, LOGMEM(set->ctx); free(ret), NULL);
+            memcpy(ret->val.nodes, set->val.nodes, set->used * sizeof *ret->val.nodes);
+        } else {
+            ret->val.nodes = NULL;
+        }
 
         ret->used = ret->size = set->used;
         ret->ctx_pos = set->ctx_pos;
@@ -901,9 +905,13 @@
         trg->used = src->used;
         trg->size = src->used;
 
-        trg->val.scnodes = ly_realloc(trg->val.scnodes, trg->size * sizeof *trg->val.scnodes);
-        LY_CHECK_ERR_RET(!trg->val.scnodes, LOGMEM(src->ctx); memset(trg, 0, sizeof *trg), );
-        memcpy(trg->val.scnodes, src->val.scnodes, src->used * sizeof *src->val.scnodes);
+        if (trg->size) {
+            trg->val.scnodes = ly_realloc(trg->val.scnodes, trg->size * sizeof *trg->val.scnodes);
+            LY_CHECK_ERR_RET(!trg->val.scnodes, LOGMEM(src->ctx); memset(trg, 0, sizeof *trg), );
+            memcpy(trg->val.scnodes, src->val.scnodes, src->used * sizeof *src->val.scnodes);
+        } else {
+            trg->val.scnodes = NULL;
+        }
     } else if (src->type == LYXP_SET_BOOLEAN) {
         set_fill_boolean(trg, src->val.bln);
     } else if (src->type == LYXP_SET_NUMBER) {
@@ -925,9 +933,13 @@
         trg->ctx_pos = src->ctx_pos;
         trg->ctx_size = src->ctx_size;
 
-        trg->val.nodes = malloc(trg->used * sizeof *trg->val.nodes);
-        LY_CHECK_ERR_RET(!trg->val.nodes, LOGMEM(src->ctx); memset(trg, 0, sizeof *trg), );
-        memcpy(trg->val.nodes, src->val.nodes, src->used * sizeof *src->val.nodes);
+        if (trg->size) {
+            trg->val.nodes = malloc(trg->size * sizeof *trg->val.nodes);
+            LY_CHECK_ERR_RET(!trg->val.nodes, LOGMEM(src->ctx); memset(trg, 0, sizeof *trg), );
+            memcpy(trg->val.nodes, src->val.nodes, src->used * sizeof *src->val.nodes);
+        } else {
+            trg->val.nodes = NULL;
+        }
         if (src->ht) {
             trg->ht = lyht_dup(src->ht);
         } else {
@@ -972,10 +984,9 @@
     set_remove_node_hash(set, set->val.nodes[idx].node, set->val.nodes[idx].type);
 
     --set->used;
-    if (set->used) {
-        memmove(&set->val.nodes[idx], &set->val.nodes[idx + 1],
-                (set->used - idx) * sizeof *set->val.nodes);
-    } else {
+    if (idx < set->used) {
+        memmove(&set->val.nodes[idx], &set->val.nodes[idx + 1], (set->used - idx) * sizeof *set->val.nodes);
+    } else if (!set->used) {
         lyxp_set_free_content(set);
     }
 }
@@ -2988,32 +2999,34 @@
     dup = calloc(1, sizeof *dup);
     LY_CHECK_ERR_GOTO(!dup, LOGMEM(ctx); ret = LY_EMEM, cleanup);
 
-    dup->tokens = malloc(exp->used * sizeof *dup->tokens);
-    LY_CHECK_ERR_GOTO(!dup->tokens, LOGMEM(ctx); ret = LY_EMEM, cleanup);
-    memcpy(dup->tokens, exp->tokens, exp->used * sizeof *dup->tokens);
+    if (exp->used) {
+        dup->tokens = malloc(exp->used * sizeof *dup->tokens);
+        LY_CHECK_ERR_GOTO(!dup->tokens, LOGMEM(ctx); ret = LY_EMEM, cleanup);
+        memcpy(dup->tokens, exp->tokens, exp->used * sizeof *dup->tokens);
 
-    dup->tok_pos = malloc(exp->used * sizeof *dup->tok_pos);
-    LY_CHECK_ERR_GOTO(!dup->tok_pos, LOGMEM(ctx); ret = LY_EMEM, cleanup);
-    memcpy(dup->tok_pos, exp->tok_pos, exp->used * sizeof *dup->tok_pos);
+        dup->tok_pos = malloc(exp->used * sizeof *dup->tok_pos);
+        LY_CHECK_ERR_GOTO(!dup->tok_pos, LOGMEM(ctx); ret = LY_EMEM, cleanup);
+        memcpy(dup->tok_pos, exp->tok_pos, exp->used * sizeof *dup->tok_pos);
 
-    dup->tok_len = malloc(exp->used * sizeof *dup->tok_len);
-    LY_CHECK_ERR_GOTO(!dup->tok_len, LOGMEM(ctx); ret = LY_EMEM, cleanup);
-    memcpy(dup->tok_len, exp->tok_len, exp->used * sizeof *dup->tok_len);
+        dup->tok_len = malloc(exp->used * sizeof *dup->tok_len);
+        LY_CHECK_ERR_GOTO(!dup->tok_len, LOGMEM(ctx); ret = LY_EMEM, cleanup);
+        memcpy(dup->tok_len, exp->tok_len, exp->used * sizeof *dup->tok_len);
 
-    dup->repeat = malloc(exp->used * sizeof *dup->repeat);
-    LY_CHECK_ERR_GOTO(!dup->repeat, LOGMEM(ctx); ret = LY_EMEM, cleanup);
-    for (i = 0; i < exp->used; ++i) {
-        if (!exp->repeat[i]) {
-            dup->repeat[i] = NULL;
-        } else {
-            for (j = 0; exp->repeat[i][j]; ++j) {}
-            /* the ending 0 as well */
-            ++j;
+        dup->repeat = malloc(exp->used * sizeof *dup->repeat);
+        LY_CHECK_ERR_GOTO(!dup->repeat, LOGMEM(ctx); ret = LY_EMEM, cleanup);
+        for (i = 0; i < exp->used; ++i) {
+            if (!exp->repeat[i]) {
+                dup->repeat[i] = NULL;
+            } else {
+                for (j = 0; exp->repeat[i][j]; ++j) {}
+                /* the ending 0 as well */
+                ++j;
 
-            dup->repeat[i] = malloc(j * sizeof **dup->repeat);
-            LY_CHECK_ERR_GOTO(!dup->repeat[i], LOGMEM(ctx); ret = LY_EMEM, cleanup);
-            memcpy(dup->repeat[i], exp->repeat[i], j * sizeof **dup->repeat);
-            dup->repeat[i][j - 1] = 0;
+                dup->repeat[i] = malloc(j * sizeof **dup->repeat);
+                LY_CHECK_ERR_GOTO(!dup->repeat[i], LOGMEM(ctx); ret = LY_EMEM, cleanup);
+                memcpy(dup->repeat[i], exp->repeat[i], j * sizeof **dup->repeat);
+                dup->repeat[i][j - 1] = 0;
+            }
         }
     }