Returned the size of locale encoded target as the size of symlinks

Made ntfs-3f conform to the standard POSIX convention of setting st_size
to the length of the symlink target without a terminating null.

(contributed by Eric Biggers)
pull/2/head
Jean-Pierre André 2017-02-11 10:04:15 +01:00
parent 376f4cbca7
commit 051a4b556b
2 changed files with 54 additions and 16 deletions

View File

@ -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);

View File

@ -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);