libyang BUGFIX change LOGVAL to LOGVAL_ERRITEM

Segfault can occur if the LOGVAR macro is called with the
ly_err_item.msg parameter, which contains a conversion specification
(character %).
diff --git a/src/common.h b/src/common.h
index 51fcbc9..38c7c28 100644
--- a/src/common.h
+++ b/src/common.h
@@ -174,6 +174,17 @@
     ly_log_location(NULL, NULL, NULL, NULL, LINE, 0); \
     ly_vlog(CTX, CODE, ##__VA_ARGS__)
 
+/**
+ * @brief Print Validation error from struct ly_err_item.
+ *
+ * String ::ly_err_item.msg cannot be used directly because it may contain the % character,
+ * which is incorrectly interpreted in this situation as a conversion specification.
+ *
+ * @param[in] CTX libyang context to store the error record. If not provided, the error is just printed.
+ * @param[in] ERRITEM pointer to ly_err_item that contains an error message.
+ */
+#define LOGVAL_ERRITEM(CTX, ERRITEM) ly_vlog(CTX, ERRITEM->vecode, "%s", ERRITEM->msg)
+
 #define LOGMEM_RET(CTX) LOGMEM(CTX); return LY_EMEM
 #define LOGINT_RET(CTX) LOGINT(CTX); return LY_EINT
 #define LOGARG_RET(CTX) LOGARG(CTX); return LY_EINVAL
diff --git a/src/plugins_types/xpath1.0.c b/src/plugins_types/xpath1.0.c
index 0f6fa39..38e7731 100644
--- a/src/plugins_types/xpath1.0.c
+++ b/src/plugins_types/xpath1.0.c
@@ -263,7 +263,7 @@
 
     if (xpath10_print_value(value->ptr, format, prefix_data, &str_value, &err)) {
         if (err) {
-            LOGVAL(NULL, err->vecode, err->msg);
+            LOGVAL_ERRITEM(NULL, err);
             ly_err_free(err);
         }
         *dynamic = 0;
diff --git a/src/tree_data.c b/src/tree_data.c
index c8434aa..699f199 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -81,7 +81,7 @@
         }
     } else if (ret) {
         if (err) {
-            LOGVAL(ctx, err->vecode, err->msg);
+            LOGVAL_ERRITEM(ctx, err);
             ly_err_free(err);
         } else {
             LOGVAL(ctx, LYVE_OTHER, "Storing value \"%.*s\" failed.", (int)value_len, value);
@@ -104,7 +104,7 @@
     ret = type->plugin->validate(ctx, type, ctx_node, tree, val, &err);
     if (ret) {
         if (err) {
-            LOGVAL(ctx, err->vecode, err->msg);
+            LOGVAL_ERRITEM(ctx, err);
             ly_err_free(err);
         } else {
             LOGVAL(ctx, LYVE_OTHER, "Resolving value \"%s\" failed.", type->plugin->print(ctx, val, LY_VALUE_CANON,
@@ -143,7 +143,7 @@
         if (ctx) {
             /* log only in case the ctx was provided as input parameter */
             LOG_LOCSET(NULL, NULL, err->path, NULL);
-            LOGVAL(ctx, err->vecode, err->msg);
+            LOGVAL_ERRITEM(ctx, err);
             LOG_LOCBACK(0, 0, 1, 0);
         }
         ly_err_free(err);
@@ -195,7 +195,7 @@
             } else {
                 LOG_LOCSET(schema, NULL, NULL, NULL);
             }
-            LOGVAL(ctx, err->vecode, err->msg);
+            LOGVAL_ERRITEM(ctx, err);
             if (err->path) {
                 LOG_LOCBACK(0, 0, 1, 0);
             } else if (ctx_node) {