lib/base: heim_config_parse_file do not leak 'newfname'
Refactor heim_config_parse_file() to use a common exit and ensure that 'newfname' is freed on all exit paths. Change-Id: Ie805ce2f9d6cbd26a3b98dc944b40864945b6d80
This commit is contained in:

committed by
Nicolas Williams

parent
58db0edea0
commit
5502fa4eca
@@ -558,7 +558,7 @@ heim_config_parse_file_multi(heim_context context,
|
|||||||
const char *str;
|
const char *str;
|
||||||
char *newfname = NULL;
|
char *newfname = NULL;
|
||||||
unsigned lineno = 0;
|
unsigned lineno = 0;
|
||||||
heim_error_code ret;
|
heim_error_code ret = 0;
|
||||||
struct fileptr f;
|
struct fileptr f;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
@@ -580,10 +580,10 @@ heim_config_parse_file_multi(heim_context context,
|
|||||||
char homebuf[MAX_PATH];
|
char homebuf[MAX_PATH];
|
||||||
|
|
||||||
if (!heim_context_get_homedir_access(context)) {
|
if (!heim_context_get_homedir_access(context)) {
|
||||||
config_include_depth--;
|
|
||||||
heim_set_error_message(context, EPERM,
|
heim_set_error_message(context, EPERM,
|
||||||
"Access to home directory not allowed");
|
"Access to home directory not allowed");
|
||||||
return EPERM;
|
ret = EPERM;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
home = roken_get_appdatadir(homebuf, sizeof(homebuf));
|
home = roken_get_appdatadir(homebuf, sizeof(homebuf));
|
||||||
@@ -592,8 +592,8 @@ heim_config_parse_file_multi(heim_context context,
|
|||||||
|
|
||||||
aret = asprintf(&newfname, "%s%s", home, &fname[1]);
|
aret = asprintf(&newfname, "%s%s", home, &fname[1]);
|
||||||
if (aret == -1 || newfname == NULL) {
|
if (aret == -1 || newfname == NULL) {
|
||||||
config_include_depth--;
|
ret = heim_enomem(context);
|
||||||
return heim_enomem(context);
|
goto out;
|
||||||
}
|
}
|
||||||
fname = newfname;
|
fname = newfname;
|
||||||
}
|
}
|
||||||
@@ -604,39 +604,34 @@ heim_config_parse_file_multi(heim_context context,
|
|||||||
*/
|
*/
|
||||||
if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 ||
|
if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 ||
|
||||||
newfname == NULL) {
|
newfname == NULL) {
|
||||||
config_include_depth--;
|
ret = heim_enomem(context);
|
||||||
return heim_enomem(context);
|
goto out;
|
||||||
}
|
}
|
||||||
fname = newfname;
|
fname = newfname;
|
||||||
#endif /* HEIM_BASE_USE_PATH_TOKENS */
|
#endif /* HEIM_BASE_USE_PATH_TOKENS */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_plist_file(fname)) {
|
if (is_plist_file(fname)) {
|
||||||
config_include_depth--;
|
|
||||||
#if defined(HAVE_FRAMEWORK_COREFOUNDATION)
|
#if defined(HAVE_FRAMEWORK_COREFOUNDATION)
|
||||||
ret = parse_plist_config(context, fname, res);
|
ret = parse_plist_config(context, fname, res);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
heim_set_error_message(context, ret,
|
heim_set_error_message(context, ret,
|
||||||
"Failed to parse plist %s", fname);
|
"Failed to parse plist %s", fname);
|
||||||
free(newfname);
|
goto out;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
heim_set_error_message(context, ENOENT,
|
heim_set_error_message(context, ENOENT,
|
||||||
"no support for plist configuration files");
|
"no support for plist configuration files");
|
||||||
return ENOENT;
|
ret = ENOENT;
|
||||||
|
goto out;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef HEIM_BASE_USE_PATH_TOKENS
|
#ifdef HEIM_BASE_USE_PATH_TOKENS
|
||||||
char *exp_fname; /* newfname might be non-NULL */
|
char *exp_fname; /* newfname might be non-NULL */
|
||||||
ret = heim_expand_path_tokens(context, fname, 1, &exp_fname, NULL);
|
ret = heim_expand_path_tokens(context, fname, 1, &exp_fname, NULL);
|
||||||
if (ret) {
|
if (ret)
|
||||||
config_include_depth--;
|
goto out;
|
||||||
free(newfname);
|
free(newfname);
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(newfname);
|
|
||||||
fname = newfname = exp_fname;
|
fname = newfname = exp_fname;
|
||||||
#endif /* HEIM_BASE_USE_PATH_TOKENS */
|
#endif /* HEIM_BASE_USE_PATH_TOKENS */
|
||||||
|
|
||||||
@@ -646,37 +641,36 @@ heim_config_parse_file_multi(heim_context context,
|
|||||||
if (f.f == NULL || fstat(fileno(f.f), &st) == -1) {
|
if (f.f == NULL || fstat(fileno(f.f), &st) == -1) {
|
||||||
if (f.f != NULL)
|
if (f.f != NULL)
|
||||||
(void) fclose(f.f);
|
(void) fclose(f.f);
|
||||||
config_include_depth--;
|
|
||||||
ret = errno;
|
ret = errno;
|
||||||
heim_set_error_message(context, ret, "open or stat %s: %s",
|
heim_set_error_message(context, ret, "open or stat %s: %s",
|
||||||
fname, strerror(ret));
|
fname, strerror(ret));
|
||||||
free(newfname);
|
goto out;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISREG(st.st_mode)) {
|
if (!S_ISREG(st.st_mode)) {
|
||||||
(void) fclose(f.f);
|
(void) fclose(f.f);
|
||||||
config_include_depth--;
|
|
||||||
heim_set_error_message(context, EISDIR, "not a regular file %s: %s",
|
heim_set_error_message(context, EISDIR, "not a regular file %s: %s",
|
||||||
fname, strerror(EISDIR));
|
fname, strerror(EISDIR));
|
||||||
free(newfname);
|
ret = EISDIR;
|
||||||
return EISDIR;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = heim_config_parse_debug(&f, res, &lineno, &str);
|
ret = heim_config_parse_debug(&f, res, &lineno, &str);
|
||||||
config_include_depth--;
|
|
||||||
fclose(f.f);
|
fclose(f.f);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret != HEIM_ERR_CONFIG_BADFORMAT) {
|
if (ret != HEIM_ERR_CONFIG_BADFORMAT) {
|
||||||
ret = HEIM_ERR_CONFIG_BADFORMAT;
|
ret = HEIM_ERR_CONFIG_BADFORMAT;
|
||||||
heim_set_error_message(context, ret, "%s:%u: %s",
|
heim_set_error_message(context, ret, "%s:%u: %s",
|
||||||
fname, lineno, str);
|
fname, lineno, str);
|
||||||
}
|
}
|
||||||
free(newfname);
|
goto out;
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
out:
|
||||||
|
config_include_depth--;
|
||||||
|
free(newfname);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
heim_error_code
|
heim_error_code
|
||||||
|
Reference in New Issue
Block a user