config_libconfig: fix xdgConfigDirectories

Fixed 2 problems:

1. Made sure the returned list is NULL terminated.
2. Allocate the duplicated string and the return list together, so the
   duplicated string will be freed as we free the list. Fixed a memory
   leak.

Fixes #324

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2020-03-01 13:15:36 +00:00
parent a8e8b747fe
commit 6b9eddae49
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
1 changed files with 25 additions and 17 deletions

View File

@ -53,26 +53,34 @@ const char *xdgConfigHome(void) {
}
const char * const * xdgConfigDirectories(void) {
char *dirs, *path, *xdgd = getenv("XDG_CONFIG_DIRS");
char **dir_list = {0};
unsigned int sep = 0;
char *xdgd = getenv("XDG_CONFIG_DIRS");
size_t count = 0;
if (!xdgd) xdgd = ":/etc/xdg:";
dirs = strdup(xdgd);
CHECK(dirs != NULL);
path = strtok(dirs, ":");
while (path) {
dir_list = realloc(dir_list, sizeof(char*) * ++sep);
CHECK(dir_list);
dir_list[sep-1] = path;
path = strtok(NULL, ":");
if (!xdgd) {
xdgd = "/etc/xdg";
}
for (int i = 0; xdgd[i]; i++) {
if (xdgd[i] == ':') {
count++;
}
}
// Store the string and the result pointers together so it can be
// freed together
char **dir_list = cvalloc(sizeof(char *) * (count + 2) + strlen(xdgd) + 1);
auto dirs = strcpy((char *)dir_list + sizeof(char *) * (count + 2), xdgd);
auto path = dirs;
for (size_t i = 0; i < count; i++) {
dir_list[i] = path;
path = strchr(path, ':');
*path = '\0';
path++;
}
dir_list[count] = path;
dir_list[count + 1] = NULL;
return (const char * const *)dir_list;
}