diff options
author | Simon McVittie <smcv@collabora.com> | 2022-10-28 12:21:29 +0100 |
---|---|---|
committer | Simon McVittie <smcv@collabora.com> | 2022-10-28 12:21:58 +0100 |
commit | 3f3a817375f8fbfc965c1357ec45a58e3ba469a0 (patch) | |
tree | 7e051b8f0cbabdf3087afc33eaba8908883d2450 /tests/readdir-rand.c | |
parent | d731ee804de4949afaff106c8c47062e88aeb603 (diff) | |
download | ostree-3f3a817375f8fbfc965c1357ec45a58e3ba469a0.tar.gz |
readdir-rand: Copy full size of struct dirent
As noted in readdir(3), in the presence of long filenames it is
possible for a directory entry to be larger than `sizeof (struct dirent)`.
Copy the full length instead.
Signed-off-by: Simon McVittie <smcv@collabora.com>
Diffstat (limited to 'tests/readdir-rand.c')
-rw-r--r-- | tests/readdir-rand.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/tests/readdir-rand.c b/tests/readdir-rand.c index f5d31ffb..cd3b3b09 100644 --- a/tests/readdir-rand.c +++ b/tests/readdir-rand.c @@ -40,6 +40,33 @@ # define READDIR_R "readdir_r" #endif +/* + * copy_dirent: + * @other: Another struct dirent + * + * Returns: a copy of @other. Free with g_free(). + */ +static struct dirent * +copy_dirent (const struct dirent *other) +{ + struct dirent *self; + size_t len; + + /* We can't just use sizeof (struct dirent) for the length to copy, + * because filenames are allowed to be longer than NAME_MAX bytes. */ + len = G_STRUCT_OFFSET (struct dirent, d_name) + strlen (other->d_name) + 1; + + if (len < other->d_reclen) + len = other->d_reclen; + + if (len < sizeof (struct dirent)) + len = sizeof (struct dirent); + + self = g_malloc0 (len); + memcpy (self, other, len); + return self; +} + static GHashTable *direntcache; static GMutex direntcache_lock; static gsize initialized; @@ -114,7 +141,7 @@ readdir (DIR *dirp) de = dir_entries_new (); g_hash_table_insert (direntcache, dirp, de); } - copy = g_memdup (ret, sizeof (struct dirent)); + copy = copy_dirent (ret); g_ptr_array_add (de->entries, copy); } else |