NTFS-3G used several different conventions for setting st_size of symlinks. Make it use the standard POSIX convention of setting st_size to the length of the link target without a terminating null.
Signed-off-by: Eric Biggers <ebigge...@gmail.com> --- src/lowntfs-3g.c | 35 +++++++++++++++++++++++++++-------- src/ntfs-3g.c | 35 +++++++++++++++++++++++++++-------- 2 files changed, 54 insertions(+), 16 deletions(-) diff --git a/src/lowntfs-3g.c b/src/lowntfs-3g.c index a91d123..bc9770a 100644 --- a/src/lowntfs-3g.c +++ b/src/lowntfs-3g.c @@ -645,11 +645,10 @@ static int junction_getstat(ntfs_inode *ni, * we still display as a symlink */ if (target || (errno == EOPNOTSUPP)) { - /* returning attribute size */ if (target) - stbuf->st_size = attr_size; + stbuf->st_size = strlen(target); else - stbuf->st_size = sizeof(ntfs_bad_reparse); + stbuf->st_size = sizeof(ntfs_bad_reparse) - 1; stbuf->st_blocks = (ni->allocated_size + 511) >> 9; stbuf->st_mode = S_IFLNK; free(target); @@ -705,7 +704,7 @@ static int ntfs_fuse_getstat(struct SECURITY_CONTEXT *scx, apply_umask(stbuf); } else { stbuf->st_size = - sizeof(ntfs_bad_reparse); + sizeof(ntfs_bad_reparse) - 1; stbuf->st_blocks = (ni->allocated_size + 511) >> 9; stbuf->st_mode = S_IFLNK; @@ -725,12 +724,11 @@ static int ntfs_fuse_getstat(struct SECURITY_CONTEXT *scx, * we still display as a symlink */ if (target || (errno == EOPNOTSUPP)) { - /* returning attribute size */ if (target) - stbuf->st_size = attr_size; + stbuf->st_size = strlen(target); else stbuf->st_size = - sizeof(ntfs_bad_reparse); + sizeof(ntfs_bad_reparse) - 1; stbuf->st_blocks = (ni->allocated_size + 511) >> 9; stbuf->st_nlink = @@ -837,8 +835,29 @@ static int ntfs_fuse_getstat(struct SECURITY_CONTEXT *scx, le64_to_cpu( intx_file->minor)); } - if (intx_file->magic == INTX_SYMBOLIC_LINK) + if (intx_file->magic == INTX_SYMBOLIC_LINK) { + char *target = NULL; + int len; + + /* st_size should be set to length of + * symlink target as multibyte string */ + len = ntfs_ucstombs( + intx_file->target, + (na->data_size - + offsetof(INTX_FILE, + target)) / + sizeof(ntfschar), + &target, 0); + if (len < 0) { + res = -errno; + free(intx_file); + ntfs_attr_close(na); + goto exit; + } + free(target); stbuf->st_mode = S_IFLNK; + stbuf->st_size = len; + } free(intx_file); } ntfs_attr_close(na); diff --git a/src/ntfs-3g.c b/src/ntfs-3g.c index 702d676..f4af89b 100644 --- a/src/ntfs-3g.c +++ b/src/ntfs-3g.c @@ -709,11 +709,10 @@ static int junction_getattr(ntfs_inode *ni, * we still display as a symlink */ if (target || (errno == EOPNOTSUPP)) { - /* returning attribute size */ if (target) - stbuf->st_size = attr_size; + stbuf->st_size = strlen(target); else - stbuf->st_size = sizeof(ntfs_bad_reparse); + stbuf->st_size = sizeof(ntfs_bad_reparse) - 1; stbuf->st_blocks = (ni->allocated_size + 511) >> 9; stbuf->st_mode = S_IFLNK; free(target); @@ -796,7 +795,7 @@ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf) goto ok; } else { stbuf->st_size = - sizeof(ntfs_bad_reparse); + sizeof(ntfs_bad_reparse) - 1; stbuf->st_blocks = (ni->allocated_size + 511) >> 9; stbuf->st_mode = S_IFLNK; @@ -816,11 +815,10 @@ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf) * we still display as a symlink */ if (target || (errno == EOPNOTSUPP)) { - /* returning attribute size */ if (target) - stbuf->st_size = attr_size; + stbuf->st_size = strlen(target); else - stbuf->st_size = sizeof(ntfs_bad_reparse); + stbuf->st_size = sizeof(ntfs_bad_reparse) - 1; stbuf->st_blocks = (ni->allocated_size + 511) >> 9; stbuf->st_nlink = le16_to_cpu(ni->mrec->link_count); stbuf->st_mode = S_IFLNK; @@ -942,8 +940,29 @@ static int ntfs_fuse_getattr(const char *org_path, struct stat *stbuf) le64_to_cpu( intx_file->minor)); } - if (intx_file->magic == INTX_SYMBOLIC_LINK) + if (intx_file->magic == INTX_SYMBOLIC_LINK) { + char *target = NULL; + int len; + + /* st_size should be set to length of + * symlink target as multibyte string */ + len = ntfs_ucstombs( + intx_file->target, + (na->data_size - + offsetof(INTX_FILE, + target)) / + sizeof(ntfschar), + &target, 0); + if (len < 0) { + res = -errno; + free(intx_file); + ntfs_attr_close(na); + goto exit; + } + free(target); stbuf->st_mode = S_IFLNK; + stbuf->st_size = len; + } free(intx_file); } ntfs_attr_close(na); -- 2.9.3 ------------------------------------------------------------------------------ _______________________________________________ ntfs-3g-devel mailing list ntfs-3g-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ntfs-3g-devel