The functionality of adding a declaration to a symbol table is also needed in __cil_copy_node_helper() and not just cil_gen_node(). Create a new function called cil_add_decl_to_symtab() to add a declaration to a symtab and refactor cil_gen_node() and __cil_copy_node_helper() to use the new function. By using the new function, __cil_copy_node_helper() will now allow duplicate declarations when appropriate. Signed-off-by: James Carter <jwcart2@xxxxxxxxx> --- libsepol/cil/src/cil_build_ast.c | 63 +++++++++++++++++++------------- libsepol/cil/src/cil_build_ast.h | 2 + libsepol/cil/src/cil_copy_ast.c | 6 ++- 3 files changed, 45 insertions(+), 26 deletions(-) diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c index 14cdce14..ec81db55 100644 --- a/libsepol/cil/src/cil_build_ast.c +++ b/libsepol/cil/src/cil_build_ast.c @@ -102,11 +102,45 @@ static int cil_allow_multiple_decls(struct cil_db *db, enum cil_flavor f_new, en return CIL_FALSE; } +int cil_add_decl_to_symtab(struct cil_db *db, symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node) +{ + int rc; + + if (symtab == NULL || datum == NULL || node == NULL) { + return SEPOL_ERR; + } + + rc = cil_symtab_insert(symtab, key, datum, node); + if (rc == SEPOL_EEXIST) { + struct cil_symtab_datum *prev; + rc = cil_symtab_get_datum(symtab, key, &prev); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Re-declaration of %s %s, but previous declaration could not be found\n",cil_node_to_string(node), key); + return SEPOL_ERR; + } + if (!cil_allow_multiple_decls(db, node->flavor, FLAVOR(prev))) { + /* multiple_decls not ok, ret error */ + struct cil_tree_node *n = NODE(prev); + cil_log(CIL_ERR, "Re-declaration of %s %s\n", + cil_node_to_string(node), key); + cil_tree_log(node, CIL_ERR, "Previous declaration of %s", + cil_node_to_string(n)); + return SEPOL_ERR; + } + /* multiple_decls is enabled and works for this datum type, add node */ + cil_list_append(prev->nodes, CIL_NODE, node); + node->data = prev; + cil_symtab_datum_destroy(datum); + free(datum); + } + + return SEPOL_OK; +} + int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor) { int rc = SEPOL_ERR; symtab_t *symtab = NULL; - struct cil_symtab_datum *prev; rc = cil_verify_name((const char*)key, nflavor); if (rc != SEPOL_OK) { @@ -121,30 +155,9 @@ int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_s ast_node->data = datum; ast_node->flavor = nflavor; - if (symtab != NULL) { - rc = cil_symtab_insert(symtab, (hashtab_key_t)key, datum, ast_node); - if (rc == SEPOL_EEXIST) { - rc = cil_symtab_get_datum(symtab, (hashtab_key_t)key, &prev); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Re-declaration of %s %s, but previous declaration could not be found\n",cil_node_to_string(ast_node), key); - goto exit; - } - if (!cil_allow_multiple_decls(db, nflavor, FLAVOR(prev))) { - /* multiple_decls not ok, ret error */ - struct cil_tree_node *node = NODE(prev); - cil_log(CIL_ERR, "Re-declaration of %s %s\n", - cil_node_to_string(ast_node), key); - cil_tree_log(node, CIL_ERR, "Previous declaration of %s", - cil_node_to_string(node)); - rc = SEPOL_ERR; - goto exit; - } - /* multiple_decls is enabled and works for this datum type, add node */ - cil_list_append(prev->nodes, CIL_NODE, ast_node); - ast_node->data = prev; - cil_symtab_datum_destroy(datum); - free(datum); - } + rc = cil_add_decl_to_symtab(db, symtab, key, datum, ast_node); + if (rc != SEPOL_OK) { + goto exit; } if (ast_node->parent->flavor == CIL_MACRO) { diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h index 8153e51e..fd9053ce 100644 --- a/libsepol/cil/src/cil_build_ast.h +++ b/libsepol/cil/src/cil_build_ast.h @@ -37,6 +37,8 @@ #include "cil_tree.h" #include "cil_list.h" +int cil_add_decl_to_symtab(struct cil_db *db, symtab_t *symtab, hashtab_key_t key, struct cil_symtab_datum *datum, struct cil_tree_node *node); + int cil_gen_node(struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor); int cil_parse_to_list(struct cil_tree_node *parse_cl_head, struct cil_list *ast_cl, enum cil_flavor flavor); diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c index ed967861..12bc553c 100644 --- a/libsepol/cil/src/cil_copy_ast.c +++ b/libsepol/cil/src/cil_copy_ast.c @@ -2031,7 +2031,11 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u rc = SEPOL_ERR; goto exit; } - rc = cil_symtab_insert(symtab, ((struct cil_symtab_datum*)orig->data)->name, ((struct cil_symtab_datum*)data), new); + + rc = cil_add_decl_to_symtab(db, symtab, DATUM(orig->data)->name, DATUM(data), new); + if (rc != SEPOL_OK) { + goto exit; + } namespace = new; while (namespace->flavor != CIL_MACRO && namespace->flavor != CIL_BLOCK && namespace->flavor != CIL_ROOT) { -- 2.26.3