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