diff --git a/dissect/xfs/xfs.py b/dissect/xfs/xfs.py index 769a297..e02fd3a 100644 --- a/dissect/xfs/xfs.py +++ b/dissect/xfs/xfs.py @@ -325,7 +325,10 @@ def link(self) -> str: if not self._link: if self.inode.di_format != c_xfs.xfs_dinode_fmt.XFS_DINODE_FMT_LOCAL and self.xfs.version == 5: - fh = self.open() + # We do not use open because for non-resident symlinks self.size does not include the symlink header + runs = self.dataruns() + symlink_size = c_xfs.xfs_dsymlink_hdr.size + self.size + fh = RunlistStream(self.xfs.fh, runs, symlink_size, self.xfs.block_size) header = c_xfs.xfs_dsymlink_hdr(fh) if header.sl_magic != c_xfs.XFS_SYMLINK_MAGIC: diff --git a/tests/data/.gitattributes b/tests/data/.gitattributes new file mode 100644 index 0000000..2014686 --- /dev/null +++ b/tests/data/.gitattributes @@ -0,0 +1 @@ +xfs_symlink_long.bin.gz filter=lfs diff=lfs merge=lfs -text diff --git a/tests/data/xfs_symlink_long.bin.gz b/tests/data/xfs_symlink_long.bin.gz new file mode 100644 index 0000000..6c289d0 --- /dev/null +++ b/tests/data/xfs_symlink_long.bin.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff94bd598afb51a98eb02295d584cfc34a59dd5fde6f7161bf32c5ef1ac20b3e +size 50458 diff --git a/tests/test_xfs.py b/tests/test_xfs.py index aa2ce67..670c09f 100644 --- a/tests/test_xfs.py +++ b/tests/test_xfs.py @@ -73,6 +73,7 @@ def test_xfs_bigtime(xfs_bigtime_bin): ("tests/data/xfs_symlink_test1.bin.gz"), ("tests/data/xfs_symlink_test2.bin.gz"), ("tests/data/xfs_symlink_test3.bin.gz"), + ("tests/data/xfs_symlink_long.bin.gz"), ], ) def test_symlinks(image_file): @@ -85,4 +86,6 @@ def resolve(node): return node with gzip.open(image_file, "rb") as disk: - assert resolve(XFS(disk).get(path)).open().read() == expect + link_inode = resolve(XFS(disk).get(path)) + assert link_inode.nblocks == 1 + assert link_inode.open().read() == expect