mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-27 16:09:20 +00:00
Fixes fopen() calls on NULL paths and likely memory corrupions concerning dirname() missuses
This commit is contained in:
parent
55c25fac4f
commit
4b9bb8f8e9
1 changed files with 83 additions and 39 deletions
|
|
@ -728,19 +728,30 @@ const char* lp_config_get_default_string(const LpConfig *lpconfig, const char *s
|
|||
return lp_config_get_string(lpconfig, default_section, key, default_value);
|
||||
}
|
||||
|
||||
static char *_lp_config_dirname(char *path) {
|
||||
/*
|
||||
* WARNING: this function is very dangerous.
|
||||
* Read carefuly the folowing notices:
|
||||
* 1. The 'path' parameter may be modify by
|
||||
* the function. Be care to keep a copy of
|
||||
* the original string.
|
||||
* 2. The return pointer may points on a part of
|
||||
* 'path'. So, be care to not free the string
|
||||
* pointed by 'path' before the last used of
|
||||
* the returned pointer.
|
||||
* 3. Do not feed it after midnight
|
||||
*/
|
||||
static const char *_lp_config_dirname(char *path) {
|
||||
#ifdef _MSC_VER
|
||||
char drive[_MAX_DRIVE];
|
||||
char dir[_MAX_DIR];
|
||||
char fname[_MAX_FNAME];
|
||||
char ext[_MAX_EXT];
|
||||
static char dirname[_MAX_DRIVE + _MAX_DIR];
|
||||
_splitpath(path, drive, dir, fname, ext);
|
||||
return ms_strdup_printf("%s%s", drive, dir);
|
||||
snprintf(dirname, sizeof(dirname), "%s%s", drive, dir);
|
||||
return dirname;
|
||||
#else
|
||||
char *tmp = ms_strdup(path);
|
||||
char *dir = ms_strdup(dirname(tmp));
|
||||
ms_free(tmp);
|
||||
return dir;
|
||||
return dirname(path);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -748,12 +759,18 @@ bool_t lp_config_relative_file_exists(const LpConfig *lpconfig, const char *file
|
|||
if (lpconfig->filename == NULL) {
|
||||
return FALSE;
|
||||
} else {
|
||||
char *dir = _lp_config_dirname(lpconfig->filename);
|
||||
char *filename = ms_strdup(lpconfig->filename);
|
||||
const char *dir = _lp_config_dirname(filename);
|
||||
char *filepath = ms_strdup_printf("%s/%s", dir, filename);
|
||||
char *realfilepath = lp_realpath(filepath, NULL);
|
||||
FILE *file = fopen(realfilepath, "r");
|
||||
ms_free(dir);
|
||||
FILE *file;
|
||||
|
||||
ms_free(filename);
|
||||
ms_free(filepath);
|
||||
|
||||
if(realfilepath == NULL) return FALSE;
|
||||
|
||||
file = fopen(realfilepath, "r");
|
||||
ms_free(realfilepath);
|
||||
if (file) {
|
||||
fclose(file);
|
||||
|
|
@ -763,54 +780,81 @@ bool_t lp_config_relative_file_exists(const LpConfig *lpconfig, const char *file
|
|||
}
|
||||
|
||||
void lp_config_write_relative_file(const LpConfig *lpconfig, const char *filename, const char *data) {
|
||||
char *dup_config_file = NULL;
|
||||
const char *dir = NULL;
|
||||
char *filepath = NULL;
|
||||
char *realfilepath = NULL;
|
||||
FILE *file;
|
||||
|
||||
if (lpconfig->filename == NULL) return;
|
||||
if(strlen(data) > 0) {
|
||||
char *dir = _lp_config_dirname(lpconfig->filename);
|
||||
char *filepath = ms_strdup_printf("%s/%s", dir, filename);
|
||||
char *realfilepath = lp_realpath(filepath, NULL);
|
||||
FILE *file = fopen(realfilepath, "w");
|
||||
if(file != NULL) {
|
||||
fprintf(file, "%s", data);
|
||||
fclose(file);
|
||||
} else {
|
||||
ms_error("Could not open %s for write", realfilepath);
|
||||
}
|
||||
ms_free(dir);
|
||||
ms_free(filepath);
|
||||
ms_free(realfilepath);
|
||||
} else {
|
||||
|
||||
if(strlen(data) == 0) {
|
||||
ms_warning("%s has not been created because there is no data to write", filename);
|
||||
return;
|
||||
}
|
||||
|
||||
dup_config_file = ms_strdup(lpconfig->filename);
|
||||
dir = _lp_config_dirname(dup_config_file);
|
||||
filepath = ms_strdup_printf("%s/%s", dir, filename);
|
||||
realfilepath = lp_realpath(filepath, NULL);
|
||||
if(realfilepath == NULL) {
|
||||
ms_error("Could not resolv %s: %s", filepath, strerror(errno));
|
||||
goto end;
|
||||
}
|
||||
|
||||
file = fopen(realfilepath, "w");
|
||||
if(file == NULL) {
|
||||
ms_error("Could not open %s for write", realfilepath);
|
||||
goto end;
|
||||
}
|
||||
|
||||
fprintf(file, "%s", data);
|
||||
fclose(file);
|
||||
|
||||
end:
|
||||
ms_free(dup_config_file);
|
||||
ms_free(filepath);
|
||||
if(realfilepath) ms_free(realfilepath);
|
||||
}
|
||||
|
||||
int lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename, char *data, size_t max_length) {
|
||||
char *dir;
|
||||
char *filepath;
|
||||
FILE *file;
|
||||
char* realfilepath;
|
||||
char *dup_config_file = NULL;
|
||||
const char *dir = NULL;
|
||||
char *filepath = NULL;
|
||||
FILE *file = NULL;
|
||||
char* realfilepath = NULL;
|
||||
|
||||
if (lpconfig->filename == NULL) return -1;
|
||||
dir = _lp_config_dirname(lpconfig->filename);
|
||||
|
||||
dup_config_file = ms_strdup(lpconfig->filename);
|
||||
dir = _lp_config_dirname(dup_config_file);
|
||||
filepath = ms_strdup_printf("%s/%s", dir, filename);
|
||||
realfilepath = lp_realpath(filepath, NULL);
|
||||
if(realfilepath == NULL) {
|
||||
ms_error("Could not resolv %s: %s", filepath, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
file = fopen(realfilepath, "r");
|
||||
if(file != NULL) {
|
||||
if(fread(data, 1, max_length, file)<=0) {
|
||||
ms_error("%s could not be loaded. %s", realfilepath, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
fclose(file);
|
||||
} else {
|
||||
if(file == NULL) {
|
||||
ms_error("Could not open %s for read. %s", realfilepath, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
ms_free(dir);
|
||||
|
||||
if(fread(data, 1, max_length, file)<=0) {
|
||||
ms_error("%s could not be loaded. %s", realfilepath, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
ms_free(dup_config_file);
|
||||
ms_free(filepath);
|
||||
ms_free(realfilepath);
|
||||
return 0;
|
||||
|
||||
err:
|
||||
ms_free(dir);
|
||||
ms_free(filepath);
|
||||
ms_free(realfilepath);
|
||||
ms_free(filepath);
|
||||
if(realfilepath) ms_free(realfilepath);
|
||||
return -1;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue