diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2015-07-13 09:46:17 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2015-07-13 09:53:56 -0700 |
commit | 3828942550fba1f88136ffbc018a72bdeb930902 (patch) | |
tree | 3208609270898f3cabf494a7ecb6394f7d6ee4cd /src/compare.c | |
parent | d95457e0071f26b1e524c754adf211abdd53d0fa (diff) | |
download | tar-3828942550fba1f88136ffbc018a72bdeb930902.tar.gz |
tar: port -d to longer symlinks
* src/compare.c (diff_symlink):
Don't use alloca on symlink length; it might be too big for the stack.
Don't assume that readlinkat's return value fits in 'int'.
Prefer memcmp to strncmp where either will do.
Diffstat (limited to 'src/compare.c')
-rw-r--r-- | src/compare.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/compare.c b/src/compare.c index d29cfdd4..7ed45584 100644 --- a/src/compare.c +++ b/src/compare.c @@ -270,11 +270,12 @@ diff_link (void) static void diff_symlink (void) { + char buf[1024]; size_t len = strlen (current_stat_info.link_name); - char *linkbuf = alloca (len + 1); + char *linkbuf = len < sizeof buf ? buf : xmalloc (len + 1); - int status = readlinkat (chdir_fd, current_stat_info.file_name, - linkbuf, len + 1); + ssize_t status = readlinkat (chdir_fd, current_stat_info.file_name, + linkbuf, len + 1); if (status < 0) { @@ -285,8 +286,11 @@ diff_symlink (void) report_difference (¤t_stat_info, NULL); } else if (status != len - || strncmp (current_stat_info.link_name, linkbuf, len) != 0) + || memcmp (current_stat_info.link_name, linkbuf, len) != 0) report_difference (¤t_stat_info, _("Symlink differs")); + + if (linkbuf != buf) + free (linkbuf); } #endif |