aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2017-12-30 22:18:12 +0800
committerTing-Wei Lan <lantw44@gmail.com>2018-01-02 14:06:09 +0800
commitdf8d825b7949225ec9507d912ccdc144dfb5c166 (patch)
tree7b04a2d528983ec7b44a084d50e7a088bacf07d2
parentc080ad1bddbd32382e13e5d0b0540281d3b9b86f (diff)
downloadwspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar
wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar.gz
wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar.bz2
wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar.lz
wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar.xz
wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.tar.zst
wspkg-df8d825b7949225ec9507d912ccdc144dfb5c166.zip
freebsd: Fix memory leak in freebsd.ports.find
In function read_entries, we have to keep pointers returned by getline in an array to be able to free them even if the man page in FreeBSD says they will be freed when hdestroy is called. It turns out that the man page is incorrect after reading the source code and POSIX standard. In function write_maps, we can reset neither line nor len variable because it will cause getline to malloc a new buffer every time it is called. If we don't modify the values of these two variables, getline will use realloc when it needs more space and we only have to free it after leaving the loop. I know freebsd.ports.find is a short-lived program and leaking memory won't cause problems, but I still think we should do memory management properly to allow using valgrind to check the program.
-rw-r--r--freebsd/freebsd.ports.find.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/freebsd/freebsd.ports.find.c b/freebsd/freebsd.ports.find.c
index 309ea89..852c2c3 100644
--- a/freebsd/freebsd.ports.find.c
+++ b/freebsd/freebsd.ports.find.c
@@ -13,6 +13,9 @@
#define msg(...) fprintf(stderr, __VA_ARGS__)
#define msgstr(x) fputs((x), stderr)
+static char *index_lines[HASH_TABLE_SIZE];
+static size_t index_count = 0;
+
static void write_maps (const char* list_file) {
FILE* fp = fopen (list_file, "r");
if (fp == NULL) {
@@ -39,10 +42,10 @@ static void write_maps (const char* list_file) {
}
printf ("%-32s %s\n", line, hresult->data);
- line = NULL;
- len = 0;
}
+ free (line);
+
if (!feof (fp)) {
msgstr ("Fail to read the whole list file\n");
perror ("getline");
@@ -101,15 +104,18 @@ static void read_entries (const char* index_file) {
.key = pkgname,
.data = fullpath
};
- if (hsearch (hentry, ENTER) == NULL) {
+ if (hsearch (hentry, ENTER) == NULL || index_count >= HASH_TABLE_SIZE) {
msgstr ("The hash table is full!\n");
exit (5);
}
+ index_lines[index_count++] = line;
line = NULL;
len = 0;
}
+ free (line);
+
if (!feof (fp)) {
msgstr ("Fail to read the whole index file\n");
perror ("getline");
@@ -135,5 +141,11 @@ int main (int argc, char* argv[]) {
read_entries (argv[2]);
write_maps (argv[1]);
+ for (size_t i = 0; i < index_count; i++) {
+ free (index_lines[i]);
+ }
+
+ hdestroy ();
+
return 0;
}