mirror of
https://gitlab.com/apparmor/apparmor
synced 2025-08-21 17:47:10 +00:00
Fix issues introduced in coverity's snapshot 89167 - CID 532796: (#4 of 4): Resource leak (RESOURCE_LEAK) Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
173 lines
3.9 KiB
C++
173 lines
3.9 KiB
C++
/*
|
|
* Copyright (c) 2025
|
|
* Canonical Ltd. (All rights reserved)
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of version 2 of the GNU General Public
|
|
* License published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, contact Canonical Ltd.
|
|
*/
|
|
|
|
#include "symtab.h"
|
|
|
|
template <typename T>
|
|
int symtab::add_var(const char *var, T value)
|
|
{
|
|
char *var_name = variable::process_var(var);
|
|
if (!var_name)
|
|
return 1;
|
|
|
|
const auto search = my_symtab.find(var_name);
|
|
if (search != my_symtab.end()) {
|
|
/* already existing variable */
|
|
PERROR("'%s' is already defined\n", var);
|
|
free(var_name);
|
|
return 1;
|
|
}
|
|
my_symtab.emplace(var_name, variable(var_name, value));
|
|
free(var_name);
|
|
return 0;
|
|
}
|
|
|
|
int symtab::add_var(const char *var, int value)
|
|
{
|
|
return add_var<int>(var, value);
|
|
}
|
|
|
|
int symtab::add_var(const char *var, struct value_list *value)
|
|
{
|
|
return add_var<struct value_list *>(var, value);
|
|
}
|
|
|
|
int symtab::add_var(const char *var_name, const char *value)
|
|
{
|
|
/* note that here var_name must be processed already */
|
|
const auto search = my_symtab.find(var_name);
|
|
if (search != my_symtab.end()) {
|
|
/* already existing variable */
|
|
PERROR("'%s' is already defined\n", var_name);
|
|
return 1;
|
|
}
|
|
my_symtab.emplace(var_name, variable(var_name, value));
|
|
return 0;
|
|
}
|
|
|
|
|
|
int symtab::add_var(variable var)
|
|
{
|
|
const auto search = my_symtab.find(var.var_name);
|
|
if (search != my_symtab.end()) {
|
|
/* already existing variable */
|
|
PERROR("'%s' is already defined\n", var.var_name.c_str());
|
|
return 1;
|
|
}
|
|
my_symtab.emplace(var.var_name, var);
|
|
return 0;
|
|
}
|
|
|
|
variable *symtab::lookup_existing_symbol(const char *var_name)
|
|
{
|
|
if (!var_name)
|
|
return nullptr;
|
|
|
|
const auto var = my_symtab.find(var_name);
|
|
if (var == my_symtab.end()) {
|
|
return nullptr;
|
|
}
|
|
return &(var->second);
|
|
}
|
|
|
|
int symtab::add_set_value(const char *var_name, struct value_list *value)
|
|
{
|
|
char *pvar_name = variable::process_var(var_name);
|
|
variable *var = lookup_existing_symbol(pvar_name);
|
|
if (!var) {
|
|
PERROR("Failed to find declaration for: %s\n", pvar_name);
|
|
free(pvar_name);
|
|
return 1;
|
|
}
|
|
free(pvar_name);
|
|
return var->add_set_value(value);
|
|
}
|
|
|
|
variable *symtab::delete_var(const char *var_name)
|
|
{
|
|
variable *var = lookup_existing_symbol(var_name);
|
|
if (!var) {
|
|
return var;
|
|
}
|
|
if (var->type != sd_set) {
|
|
PERROR("ASSERT: delete_set_var: deleting %s but is a boolean variable\n",
|
|
var_name);
|
|
exit(1);
|
|
}
|
|
variable *save = new variable(*var);
|
|
my_symtab.erase(var->var_name);
|
|
return save;
|
|
}
|
|
|
|
void symtab::free_symtab()
|
|
{
|
|
my_symtab.erase(my_symtab.begin(), my_symtab.end());
|
|
}
|
|
|
|
void symtab::dump(bool do_expanded)
|
|
{
|
|
for (auto var : my_symtab) {
|
|
var.second.dump(do_expanded);
|
|
}
|
|
}
|
|
|
|
void symtab::expand_variables()
|
|
{
|
|
for (auto var : my_symtab) {
|
|
if (var.second.type != sd_boolean)
|
|
var.second.expand_variable();
|
|
}
|
|
}
|
|
|
|
|
|
variable *symtab::get_set_var(const char *name)
|
|
{
|
|
char *var_name = variable::process_var(name);
|
|
variable *var = lookup_existing_symbol(var_name);
|
|
if (!var) {
|
|
goto out;
|
|
}
|
|
if (var->type != sd_set) {
|
|
PERROR("Variable %s is not a set variable\n", var_name);
|
|
var = nullptr;
|
|
goto out;
|
|
}
|
|
var->expand_variable();
|
|
out:
|
|
free(var_name);
|
|
return var;
|
|
}
|
|
|
|
variable *symtab::get_boolean_var(const char *name)
|
|
{
|
|
char *var_name = variable::process_var(name);
|
|
variable *var = lookup_existing_symbol(var_name);
|
|
if (!var) {
|
|
goto out;
|
|
}
|
|
if (var->type != sd_boolean) {
|
|
PERROR("Variable %s is not a boolean variable\n", var_name);
|
|
var = nullptr;
|
|
goto out;
|
|
}
|
|
out:
|
|
free(var_name);
|
|
return var;
|
|
}
|
|
|
|
std::unordered_map<std::string, variable> symtab::my_symtab;
|