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) {