From: Colin Vidal Date: Tue, 21 Oct 2025 13:08:47 +0000 (+0200) Subject: cfg_obj_t file is now a refcounted string X-Git-Tag: v9.21.15~43^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0d8c4044ab13e7d3b2dd0a7e25dbca34c08f2cdd;p=thirdparty%2Fbind9.git cfg_obj_t file is now a refcounted string In order to reduce the lifecycle dependency of a `cfg_obj_t` on its parser, the `file` field needs its own reference count, so it isn't deleted when the parser is. It is now stored as a subsidiary `cfg_obj_t` object of type string. --- diff --git a/lib/isccfg/include/isccfg/grammar.h b/lib/isccfg/include/isccfg/grammar.h index 6c3c1cb39b5..ae15fd9ab2a 100644 --- a/lib/isccfg/include/isccfg/grammar.h +++ b/lib/isccfg/include/isccfg/grammar.h @@ -198,7 +198,7 @@ struct cfg_obj { isccfg_duration_t duration; } value; isc_refcount_t references; /*%< reference counter */ - const char *file; + cfg_obj_t *file; /*%< refcounted string */ unsigned int line; cfg_parser_t *pctx; }; diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 07bc4879faf..8a036f558bd 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -3610,24 +3610,23 @@ have_current_file(cfg_parser_t *pctx) { return true; } -static char * +static cfg_obj_t * current_file(cfg_parser_t *pctx) { - static char none[] = "none"; cfg_listelt_t *elt; cfg_obj_t *fileobj; if (!have_current_file(pctx)) { - return none; + return NULL; } elt = ISC_LIST_TAIL(pctx->open_files->value.list); if (elt == NULL) { /* shouldn't be possible, but... */ - return none; + return NULL; } fileobj = elt->obj; INSIST(fileobj->type == &cfg_type_qstring); - return fileobj->value.string.base; + return fileobj; } static void @@ -3646,7 +3645,8 @@ parser_complain(cfg_parser_t *pctx, bool is_warning, unsigned int flags, where[0] = '\0'; if (have_current_file(pctx)) { - snprintf(where, sizeof(where), "%s:%u: ", current_file(pctx), + snprintf(where, sizeof(where), + "%s:%u: ", cfg_obj_asstring(current_file(pctx)), pctx->line); } else if (pctx->buf_name != NULL) { snprintf(where, sizeof(where), "%s: ", pctx->buf_name); @@ -3714,8 +3714,8 @@ cfg_obj_log(const cfg_obj_t *obj, int level, const char *fmt, ...) { va_end(ap); if (obj->file != NULL) { - isc_log_write(CAT, MOD, level, "%s:%u: %s", obj->file, - obj->line, msgbuf); + isc_log_write(CAT, MOD, level, "%s:%u: %s", + cfg_obj_asstring(obj->file), obj->line, msgbuf); } else { isc_log_write(CAT, MOD, level, "%s", msgbuf); } @@ -3725,7 +3725,7 @@ const char * cfg_obj_file(const cfg_obj_t *obj) { REQUIRE(obj != NULL); - return obj->file; + return cfg_obj_asstring(obj->file); } unsigned int @@ -3738,18 +3738,21 @@ cfg_obj_line(const cfg_obj_t *obj) { isc_result_t cfg_create_obj(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) { cfg_obj_t *obj; + cfg_obj_t *file = NULL; REQUIRE(pctx != NULL); REQUIRE(type != NULL); REQUIRE(ret != NULL && *ret == NULL); obj = isc_mem_get(pctx->mctx, sizeof(cfg_obj_t)); - *obj = (cfg_obj_t){ .type = type, - .file = current_file(pctx), - .line = pctx->line, - .pctx = pctx }; + *obj = (cfg_obj_t){ .type = type, .line = pctx->line, .pctx = pctx }; isc_refcount_init(&obj->references, 1); + file = current_file(pctx); + if (file != NULL) { + cfg_obj_attach(file, &obj->file); + } + *ret = obj; return ISC_R_SUCCESS; @@ -3815,6 +3818,10 @@ cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) { *objp = NULL; if (isc_refcount_decrement(&obj->references) == 1) { + if (obj->file != NULL) { + cfg_obj_destroy(obj->file->pctx, &obj->file); + } + obj->type->rep->free(pctx, obj); isc_refcount_destroy(&obj->references); isc_mem_put(pctx->mctx, obj, sizeof(cfg_obj_t));