From a830f7dfa6d40d9c90dfdd9adbd190ecce936d6c Mon Sep 17 00:00:00 2001 From: Yorhel <git@yorhel.nl> Date: Thu, 17 Aug 2017 17:04:48 +0200 Subject: [PATCH] Use C99 flexible array member for struct dir This should fix https://dev.yorhel.nl/ncdu/bug/99 - with the downside that this requires a C99 compiler. I also replaced all occurrences of static allocation of struct dir with use dynamic allocation, because I wasn't really sure if static allocation of flexible structs is allowed. In the case of dirlist.c the dynamic allocation is likely required anyway, because it does store a few bytes in the name field. --- src/dir_import.c | 7 +++++-- src/dirlist.c | 10 +++++----- src/global.h | 2 +- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/dir_import.c b/src/dir_import.c index 48a9e82..68c39fe 100644 --- a/src/dir_import.c +++ b/src/dir_import.c @@ -431,10 +431,13 @@ static int itemdir(uint64_t dev) { static int iteminfo(struct dir **item, uint64_t dev, int isdir) { - static struct dir dir; - struct dir *tmp, *d = &dir; + static struct dir *dirbuf; + struct dir *tmp, *d; uint64_t iv; + if(!dirbuf) + dirbuf = malloc(sizeof(struct dir)); + d = dirbuf; memset(d, 0, sizeof(struct dir)); d->flags |= isdir ? FF_DIR : FF_FILE; d->dev = dev; diff --git a/src/dirlist.c b/src/dirlist.c index 50b90f0..893382c 100644 --- a/src/dirlist.c +++ b/src/dirlist.c @@ -40,8 +40,7 @@ int dirlist_sort_desc = 1, dirlist_hidden = 0; /* private state vars */ -static struct dir dirlist_parent_alloc; -static struct dir *head, *head_real, *selected, *top = NULL; +static struct dir *parent_alloc, *head, *head_real, *selected, *top = NULL; @@ -206,14 +205,15 @@ void dirlist_open(struct dir *d) { head_real = head = dirlist_sort(head); /* set the reference to the parent dir */ - dirlist_parent_alloc.flags &= ~FF_BSEL; - dirlist_parent_alloc.flags |= FF_DIR; if(d->parent) { - dirlist_parent = &dirlist_parent_alloc; + if(!parent_alloc) + parent_alloc = calloc(1, SDIRSIZE + 3); + dirlist_parent = parent_alloc; strcpy(dirlist_parent->name, ".."); dirlist_parent->next = head; dirlist_parent->parent = d; dirlist_parent->sub = d; + dirlist_parent->flags = FF_DIR; head = dirlist_parent; } else dirlist_parent = NULL; diff --git a/src/global.h b/src/global.h index 4cd02e1..8c02461 100644 --- a/src/global.h +++ b/src/global.h @@ -66,7 +66,7 @@ struct dir { struct dir *parent, *next, *prev, *sub, *hlnk; int items; unsigned char flags; - char name[3]; /* must be large enough to hold ".." */ + char name[]; }; /* sizeof(total dir) = SDIRSIZE + strlen(name) = offsetof(struct dir, name) + strlen(name) + 1 */ #define SDIRSIZE (offsetof(struct dir, name)+1) -- GitLab