From a90c39afc9d69a599f32a28b53fe4bdbcef059e0 Mon Sep 17 00:00:00 2001 From: Roman Janota Date: Wed, 23 Sep 2026 11:43:49 +0200 Subject: [PATCH 1/3] ly_array BUGFIX prealloc to the requested count LYA_PREALLOC() documents COUNT as the new count of the array, but realloc() still sized it as the current count plus COUNT, the meaning of the removed LY_ARRAY_CREATE. Every growth, including each LYA_ADD(), allocated about twice the memory needed. The callers converted from LY_ARRAY_CREATE that append to a non-empty array kept passing only the number of added items and worked only thanks to the over-allocation. Pass the total count there. The array is also never shrunk below its current count, so the count cannot exceed the allocation, and the macro locals no longer shadow variables the COUNT expression may use. --- src/diff.c | 2 +- src/ly_array.h | 24 +++++++++++++----------- src/path.c | 2 +- src/schema_compile.h | 2 +- src/schema_compile_node.c | 4 ++-- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/diff.c b/src/diff.c index e22f7c949..0ece51d50 100644 --- a/src/diff.c +++ b/src/diff.c @@ -824,7 +824,7 @@ lyd_diff_userord_attrs(const struct lyd_node *first, const struct lyd_node *seco */ if (*op == LYD_DIFF_OP_CREATE) { /* insert the instance */ - LYA_PREALLOC(userord_item->inst, 1, LOGMEM(schema->module->ctx); rc = LY_EMEM; goto cleanup); + LYA_PREALLOC(userord_item->inst, LYA_COUNT(userord_item->inst) + 1, LOGMEM(schema->module->ctx); rc = LY_EMEM; goto cleanup); if (second_pos < LYA_COUNT(userord_item->inst)) { memmove(userord_item->inst + second_pos + 1, userord_item->inst + second_pos, (LYA_COUNT(userord_item->inst) - second_pos) * sizeof *userord_item->inst); diff --git a/src/ly_array.h b/src/ly_array.h index 07681877c..081f8e108 100644 --- a/src/ly_array.h +++ b/src/ly_array.h @@ -88,7 +88,7 @@ extern "C" { * Does not set the size information, it is supposed to be incremented via ::LYA_INCREMENT * when the items are filled. * - * Any new memory is zeroed. + * Any new memory is zeroed. The array is never shrunk below its current count. * * @param[in,out] ARRAY Sized array to manipulate. * @param[in] COUNT New count (size) of the items in the array. @@ -96,18 +96,20 @@ extern "C" { */ #define LYA_PREALLOC(ARRAY, COUNT, EACTION) \ { \ - LYA_COUNT_T orig_count = LYA_COUNT(ARRAY); \ - void *mem = realloc((ARRAY) ? (LYA_COUNT_T *)(ARRAY) - 1 : NULL, \ - sizeof(LYA_COUNT_T) + (orig_count + COUNT) * sizeof *(ARRAY)); \ - if (!mem) { \ - EACTION; \ + LYA_COUNT_T lya_prealloc_orig = LYA_COUNT(ARRAY); \ + LYA_COUNT_T lya_prealloc_count = (COUNT); \ + if (lya_prealloc_count < lya_prealloc_orig) { \ + lya_prealloc_count = lya_prealloc_orig; \ } \ - void *new_array = (LYA_COUNT_T *)mem + 1; \ - memcpy(&(ARRAY), &new_array, sizeof(ARRAY)); \ - LYA_COUNT_(ARRAY) = orig_count; \ - if ((COUNT) > orig_count) { \ - memset((ARRAY) + orig_count, 0, ((COUNT) - orig_count) * sizeof *(ARRAY)); \ + void *lya_prealloc_mem = realloc((ARRAY) ? (LYA_COUNT_T *)(ARRAY) - 1 : NULL, \ + sizeof(LYA_COUNT_T) + lya_prealloc_count * sizeof *(ARRAY)); \ + if (!lya_prealloc_mem) { \ + EACTION; \ } \ + void *lya_prealloc_array = (LYA_COUNT_T *)lya_prealloc_mem + 1; \ + memcpy(&(ARRAY), &lya_prealloc_array, sizeof(ARRAY)); \ + LYA_COUNT_(ARRAY) = lya_prealloc_orig; \ + memset((ARRAY) + lya_prealloc_orig, 0, (lya_prealloc_count - lya_prealloc_orig) * sizeof *(ARRAY)); \ } /** diff --git a/src/path.c b/src/path.c index 5cccf05a1..d5e59dce7 100644 --- a/src/path.c +++ b/src/path.c @@ -974,7 +974,7 @@ ly_path_append(const struct ly_ctx *ctx, const struct ly_path *src, struct ly_pa return LY_SUCCESS; } - LYA_PREALLOC(*dst, LYA_COUNT(src), LOGMEM(ctx); return LY_EMEM); + LYA_PREALLOC(*dst, LYA_COUNT(*dst) + LYA_COUNT(src), LOGMEM(ctx); return LY_EMEM); LYA_FOR(src, u) { LYA_ADD_ITEM(*dst, p, LOGMEM(ctx); rc = LY_EMEM; goto cleanup); p->node = src[u].node; diff --git a/src/schema_compile.h b/src/schema_compile.h index 9337760b9..5b3adbde7 100644 --- a/src/schema_compile.h +++ b/src/schema_compile.h @@ -186,7 +186,7 @@ struct lysc_unres_dflt { if (ORIG_ARRAY) { \ LYA_COUNT_T __u, __new_start; \ __new_start = LYA_COUNT(NEW_ARRAY); \ - LYA_PREALLOC(NEW_ARRAY, LYA_COUNT(ORIG_ARRAY), LOGMEM(CTX); return LY_EMEM); \ + LYA_PREALLOC(NEW_ARRAY, __new_start + LYA_COUNT(ORIG_ARRAY), LOGMEM(CTX); return LY_EMEM); \ LYA_FOR(ORIG_ARRAY, __u) { \ LYA_INCREMENT(NEW_ARRAY); \ LY_CHECK_RET(DUP_FUNC(CTX, PMOD, PARENT, PARENT_STMT, &(ORIG_ARRAY)[__u], &(NEW_ARRAY)[__new_start + __u])); \ diff --git a/src/schema_compile_node.c b/src/schema_compile_node.c index 6a87e54aa..2ad151b97 100644 --- a/src/schema_compile_node.c +++ b/src/schema_compile_node.c @@ -1450,8 +1450,8 @@ lys_compile_type_union(struct lysc_ctx *ctx, struct lysp_type *ptypes, struct ly if (utypes[u + additional]->basetype == LY_TYPE_UNION) { /* add space for additional types from the union subtype */ un_aux = (struct lysc_type_union *)utypes[u + additional]; - LYA_PREALLOC(utypes, LYA_COUNT(ptypes) + additional + LYA_COUNT(un_aux->types) - LYA_COUNT(utypes), - LOGMEM(ctx->ctx); rc = LY_EMEM; goto cleanup); + LYA_PREALLOC(utypes, LYA_COUNT(ptypes) + additional + LYA_COUNT(un_aux->types), LOGMEM(ctx->ctx); + rc = LY_EMEM; goto cleanup); /* copy subtypes of the subtype union */ for (v = 0; v < LYA_COUNT(un_aux->types); ++v) { From c3b09462fffb48fbd7b900d51c511275fcb458dd Mon Sep 17 00:00:00 2001 From: Roman Janota Date: Wed, 23 Sep 2026 11:49:27 +0200 Subject: [PATCH 2/3] SOVERSION bump to version 5.11.2 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 72d8c54e9..2c8910777 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,7 +67,7 @@ set(LIBYANG_VERSION ${LIBYANG_MAJOR_VERSION}.${LIBYANG_MINOR_VERSION}.${LIBYANG_ # set version of the library set(LIBYANG_MAJOR_SOVERSION 5) set(LIBYANG_MINOR_SOVERSION 11) -set(LIBYANG_MICRO_SOVERSION 1) +set(LIBYANG_MICRO_SOVERSION 2) set(LIBYANG_SOVERSION_FULL ${LIBYANG_MAJOR_SOVERSION}.${LIBYANG_MINOR_SOVERSION}.${LIBYANG_MICRO_SOVERSION}) set(LIBYANG_SOVERSION ${LIBYANG_MAJOR_SOVERSION}) From acdb9ee3ad79feb6da47b1f893a5c74d02c60340 Mon Sep 17 00:00:00 2001 From: Roman Janota Date: Wed, 23 Sep 2026 11:49:27 +0200 Subject: [PATCH 3/3] VERSION bump to version 6.4.4 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c8910777..ceab5a8ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,7 +61,7 @@ set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) # set version of the project set(LIBYANG_MAJOR_VERSION 6) set(LIBYANG_MINOR_VERSION 4) -set(LIBYANG_MICRO_VERSION 3) +set(LIBYANG_MICRO_VERSION 4) set(LIBYANG_VERSION ${LIBYANG_MAJOR_VERSION}.${LIBYANG_MINOR_VERSION}.${LIBYANG_MICRO_VERSION}) # set version of the library