diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-04-10 17:16:05 +0200 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2023-04-12 20:41:34 +0200 |
commit | 8059c42315a3ed3726b9b0a4e6293b1cccbaacc0 (patch) | |
tree | d663deea60cc97c87f5373ca7da06a48d2e3dc0c /bin/gensquashfs/src | |
parent | ec289120f5a8edef86037945ad3ab30f24534cbd (diff) |
Cleanup: gensquashfs: split readlink handling out of directory scan
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'bin/gensquashfs/src')
-rw-r--r-- | bin/gensquashfs/src/fstree_from_dir.c | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/bin/gensquashfs/src/fstree_from_dir.c b/bin/gensquashfs/src/fstree_from_dir.c index 137900d..21c4b78 100644 --- a/bin/gensquashfs/src/fstree_from_dir.c +++ b/bin/gensquashfs/src/fstree_from_dir.c @@ -190,6 +190,36 @@ static void discard_node(tree_node_t *root, tree_node_t *n) free(n); } +static char *read_link(const struct stat *sb, int dir_fd, const char *name) +{ + size_t size; + char *out; + + if ((sizeof(sb->st_size) > sizeof(size_t)) && sb->st_size > SIZE_MAX) { + errno = EOVERFLOW; + return NULL; + } + + if (SZ_ADD_OV((size_t)sb->st_size, 1, &size)) { + errno = EOVERFLOW; + return NULL; + } + + out = calloc(1, size); + if (out == NULL) + return NULL; + + if (readlinkat(dir_fd, name, out, (size_t)sb->st_size) < 0) { + int temp = errno; + free(out); + errno = temp; + return NULL; + } + + out[sb->st_size] = '\0'; + return out; +} + static int populate_dir(int dir_fd, fstree_t *fs, tree_node_t *root, dev_t devstart, scan_node_callback cb, void *user, unsigned int flags) @@ -236,29 +266,11 @@ static int populate_dir(int dir_fd, fstree_t *fs, tree_node_t *root, continue; if (S_ISLNK(sb.st_mode)) { - size_t size; - - if ((sizeof(sb.st_size) > sizeof(size_t)) && - sb.st_size > SIZE_MAX) { - errno = EOVERFLOW; - goto fail_rdlink; - } - - if (SZ_ADD_OV((size_t)sb.st_size, 1, &size)) { - errno = EOVERFLOW; - goto fail_rdlink; - } - - extra = calloc(1, size); - if (extra == NULL) - goto fail_rdlink; - - if (readlinkat(dir_fd, ent->d_name, - extra, (size_t)sb.st_size) < 0) { - goto fail_rdlink; + extra = read_link(&sb, dir_fd, ent->d_name); + if (extra == NULL) { + perror("readlink"); + goto fail; } - - extra[sb.st_size] = '\0'; } if (!(flags & DIR_SCAN_KEEP_TIME)) @@ -310,8 +322,6 @@ static int populate_dir(int dir_fd, fstree_t *fs, tree_node_t *root, closedir(dir); return 0; -fail_rdlink: - perror("readlink"); fail: closedir(dir); free(extra); |