Skip to content

Commit fc060bb

Browse files
authored
Add symlink testing (#27)
* Add symlink testing * Handle fast symlinks * Bump version * Fix test image generation * Handle when the i_size is malformed and reading a fast symlink
1 parent 3d6b39e commit fc060bb

12 files changed

Lines changed: 36 additions & 21 deletions

_test_image.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ trap "rm -r \"$tmp_dir\"" EXIT
2828
echo "[test] Using temporary directory: $tmp_dir"
2929
echo "[test] Generating files..."
3030
echo "hello world" >"$tmp_dir"/test.txt
31+
ln -s test.txt "$tmp_dir"/symlink.txt
3132
for i in {1..1000}; do
3233
echo "echo "hello world" >>'$tmp_dir/test.txt'"
3334
done | xargs -P "$(nproc)" -I {} bash -c '{}'
@@ -43,7 +44,7 @@ done | xargs -P "$(nproc)" -I {} bash -c '{}'
4344
mkimage test32 "$tmp_dir" 20 -O ^64bit
4445
mkimage test64 "$tmp_dir" 20 -O 64bit
4546

46-
rm -f "$tmp_dir"/test*.txt
47+
rm -f "$tmp_dir"/test*.txt "$tmp_dir"/symlink.txt
4748
echo "[test] Generating files..."
4849

4950
echo "[test] Making image test_htree..."

ext4/block.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# pyright: reportImportCycles=false
21
import errno
32
import io
43
import os

ext4/blockdescriptor.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# pyright: reportImportCycles=false
21
from ctypes import (
32
c_uint16,
43
c_uint32,

ext4/directory.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# pyright: reportImportCycles=false
21
from ctypes import (
32
addressof,
43
c_char,

ext4/enum.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# pyright: reportImportCycles=false
21
from ctypes import (
32
c_uint8,
43
c_uint16,

ext4/extent.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# pyright: reportImportCycles=false
21
from collections.abc import Iterator
32
from ctypes import (
43
c_uint16,

ext4/htree.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# pyright: reportImportCycles=false
21
import warnings
32
from collections.abc import Generator
43
from ctypes import (

ext4/inode.py

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# pyright: reportImportCycles=false
21
from __future__ import annotations
32

43
import errno
@@ -74,6 +73,10 @@ class InodeError(Exception):
7473
pass
7574

7675

76+
class MalformedInodeError(Exception):
77+
pass
78+
79+
7780
@final
7881
class Linux1(LittleEndianStructure):
7982
_pack_ = 1
@@ -482,8 +485,22 @@ def open(
482485

483486

484487
class SymbolicLink(Inode):
488+
@property
489+
def is_fast_symlink(self) -> bool:
490+
i_blocks_lo = assert_cast(self.i_blocks_lo, int) # pyright: ignore[reportAny]
491+
return i_blocks_lo == 0 and not self.is_inline
492+
485493
def readlink(self) -> bytes:
486-
return self._open().read()
494+
if not self.is_fast_symlink:
495+
return self._open().read()
496+
497+
if self.i_size > Inode.i_block.size:
498+
raise MalformedInodeError(
499+
f"Fast symlink target too large: {self.i_size} > {Inode.i_block.size}"
500+
)
501+
502+
_ = self.volume.seek(self.offset + Inode.i_block.offset)
503+
return self.volume.read(self.i_size)
487504

488505

489506
class Directory(Inode):

ext4/struct.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# pyright: reportImportCycles=false
21
import ctypes
32
import errno
43
import warnings

ext4/superblock.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# pyright: reportImportCycles=false
21
from ctypes import (
32
c_ubyte,
43
c_uint8,

0 commit comments

Comments
 (0)