Skip to content

Commit f40ba0d

Browse files
committed
context BUGFIX manually free pcodes for a printed context
1 parent e736762 commit f40ba0d

4 files changed

Lines changed: 19 additions & 20 deletions

File tree

src/context.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1496,7 +1496,8 @@ ly_ctx_destroy(struct ly_ctx *ctx)
14961496

14971497
if (ctx->opts & LY_CTX_INT_IMMUTABLE) {
14981498
if (!ctx->parent_ctx) {
1499-
/* ctx data */
1499+
/* cached patterns and ctx data */
1500+
ly_ctx_pattern_ht_erase(ctx);
15001501
ly_ctx_data_del(ctx);
15011502
}
15021503
lyplg_clean();

src/ly_common.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,13 +534,22 @@ ly_ctx_data_del(const struct ly_ctx *ctx)
534534
}
535535

536536
void
537-
ly_ctx_ht_pattern_rec_free(struct ly_pattern_ht_rec *rec)
537+
ly_ctx_pattern_ht_erase(const struct ly_ctx *ctx)
538538
{
539-
if (!rec) {
540-
return;
539+
struct ly_ctx_shared_data *ctx_data;
540+
struct ly_ht_rec *rec;
541+
uint32_t hlist_idx, rec_idx;
542+
543+
ctx_data = ly_ctx_shared_data_get(ctx);
544+
545+
/* free all the stored records */
546+
LYHT_ITER_ALL_RECS(ctx_data->pattern_ht, hlist_idx, rec_idx, rec) {
547+
pcre2_code_free(((struct ly_pattern_ht_rec *)&rec->val)->pcode);
541548
}
542549

543-
pcre2_code_free(rec->pcode);
550+
/* we have removed all patterns (so it is empty), we can not free the ht here though, to avoid
551+
* double free, but just trick it to look empty */
552+
ctx_data->pattern_ht->used = 0;
544553
}
545554

546555
LY_ERR

src/ly_common.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -503,11 +503,11 @@ LY_ERR ly_ctx_shared_data_pattern_get(const struct ly_ctx *ctx, const char *patt
503503
void ly_ctx_shared_data_pattern_del(const struct ly_ctx *ctx, const char *pattern);
504504

505505
/**
506-
* @brief Free members of a pattern record stored in the context hash table.
506+
* @brief Free members of a pattern record stored in the context shared data hash table.
507507
*
508-
* @param[in] rec Pattern records whose members to free.
508+
* @param[in] ctx Context to use.
509509
*/
510-
void ly_ctx_ht_pattern_rec_free(struct ly_pattern_ht_rec *rec);
510+
void ly_ctx_pattern_ht_erase(const struct ly_ctx *ctx);
511511

512512
/******************************************************************************
513513
* Dictionary

src/plugins_exts.c

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -763,10 +763,6 @@ LIBYANG_API_DEF LY_ERR
763763
lyplg_ext_set_parent_ctx(struct ly_ctx *ctx, const struct ly_ctx *parent_ctx)
764764
{
765765
const struct ly_ctx *c;
766-
struct ly_ctx_shared_data *ctx_data;
767-
struct ly_ht_rec *rec;
768-
uint32_t hlist_idx;
769-
uint32_t rec_idx;
770766

771767
LY_CHECK_ARG_RET(ctx, ctx, LY_EINVAL);
772768

@@ -793,14 +789,7 @@ lyplg_ext_set_parent_ctx(struct ly_ctx *ctx, const struct ly_ctx *parent_ctx)
793789
} else {
794790
/* remove its shared and private data, this is an exception as we need to free compiled patterns
795791
* manually, since we are not destroying the whole context, we will just be using the parent's ctx data instead */
796-
ctx_data = ly_ctx_shared_data_get(ctx);
797-
LYHT_ITER_ALL_RECS(ctx_data->pattern_ht, hlist_idx, rec_idx, rec) {
798-
ly_ctx_ht_pattern_rec_free((struct ly_pattern_ht_rec *)&rec->val);
799-
}
800-
801-
/* we have removed all patterns (so it is empty), we can not free the ht here though, to avoid
802-
* double free, but just trick it to look empty */
803-
ctx_data->pattern_ht->used = 0;
792+
ly_ctx_pattern_ht_erase(ctx);
804793
ly_ctx_data_del(ctx);
805794
}
806795
} else if (!parent_ctx) {

0 commit comments

Comments
 (0)