Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion _test_image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ trap "rm -r \"$tmp_dir\"" EXIT
echo "[test] Using temporary directory: $tmp_dir"
echo "[test] Generating files..."
echo "hello world" >"$tmp_dir"/test.txt
ln -s test.txt "$tmp_dir"/symlink.txt
for i in {1..1000}; do
echo "echo "hello world" >>'$tmp_dir/test.txt'"
done | xargs -P "$(nproc)" -I {} bash -c '{}'
Expand All @@ -43,7 +44,7 @@ done | xargs -P "$(nproc)" -I {} bash -c '{}'
mkimage test32 "$tmp_dir" 20 -O ^64bit
mkimage test64 "$tmp_dir" 20 -O 64bit

rm -f "$tmp_dir"/test*.txt
rm -f "$tmp_dir"/test*.txt "$tmp_dir"/symlink.txt
echo "[test] Generating files..."

echo "[test] Making image test_htree..."
Expand Down
1 change: 0 additions & 1 deletion ext4/block.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pyright: reportImportCycles=false
import errno
import io
import os
Expand Down
1 change: 0 additions & 1 deletion ext4/blockdescriptor.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pyright: reportImportCycles=false
from ctypes import (
c_uint16,
c_uint32,
Expand Down
1 change: 0 additions & 1 deletion ext4/directory.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pyright: reportImportCycles=false
from ctypes import (
addressof,
c_char,
Expand Down
1 change: 0 additions & 1 deletion ext4/enum.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pyright: reportImportCycles=false
from ctypes import (
c_uint8,
c_uint16,
Expand Down
1 change: 0 additions & 1 deletion ext4/extent.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pyright: reportImportCycles=false
from collections.abc import Iterator
from ctypes import (
c_uint16,
Expand Down
1 change: 0 additions & 1 deletion ext4/htree.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pyright: reportImportCycles=false
import warnings
from collections.abc import Generator
from ctypes import (
Expand Down
21 changes: 19 additions & 2 deletions ext4/inode.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pyright: reportImportCycles=false
from __future__ import annotations

import errno
Expand Down Expand Up @@ -74,6 +73,10 @@ class InodeError(Exception):
pass


class MalformedInodeError(Exception):
pass


@final
class Linux1(LittleEndianStructure):
_pack_ = 1
Expand Down Expand Up @@ -482,8 +485,22 @@ def open(


class SymbolicLink(Inode):
@property
def is_fast_symlink(self) -> bool:
i_blocks_lo = assert_cast(self.i_blocks_lo, int) # pyright: ignore[reportAny]
return i_blocks_lo == 0 and not self.is_inline

def readlink(self) -> bytes:
return self._open().read()
if not self.is_fast_symlink:
return self._open().read()

if self.i_size > Inode.i_block.size:
raise MalformedInodeError(
f"Fast symlink target too large: {self.i_size} > {Inode.i_block.size}"
)

_ = self.volume.seek(self.offset + Inode.i_block.offset)
return self.volume.read(self.i_size)
Comment thread
coderabbitai[bot] marked this conversation as resolved.


class Directory(Inode):
Expand Down
1 change: 0 additions & 1 deletion ext4/struct.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pyright: reportImportCycles=false
import ctypes
import errno
import warnings
Expand Down
1 change: 0 additions & 1 deletion ext4/superblock.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# pyright: reportImportCycles=false
from ctypes import (
c_ubyte,
c_uint8,
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "ext4"
version = "1.3"
version = "1.3.1"
authors = [
{ name="Eeems", email="eeems@eeems.email" },
]
Expand Down Expand Up @@ -91,3 +91,4 @@ ignore = [
[tool.pyright]
exclude = [".venv", "build"]
reportMissingTypeStubs = false
reportImportCycles = false
22 changes: 13 additions & 9 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ def test_path_tuple(path: str | bytes, expected: tuple[bytes, ...]) -> None:
except Exception as e:
FAILED = True # pyright: ignore[reportConstantRedefinition]
print("fail")
print(" ", end="")
print(e)
print(" ", end="", file=sys.stderr)
print(e, file=sys.stderr)


def _eval_or_False(source: str) -> Any: # pyright: ignore[reportExplicitAny, reportAny] # noqa: ANN401
Expand All @@ -51,7 +51,7 @@ def _assert(source: str, debug: Callable[[], Any] | None = None) -> None: # pyr
FAILED = True # pyright: ignore[reportConstantRedefinition]
print("fail")
if debug is not None:
print(f" {debug()}")
print(f" {debug()}", file=sys.stderr)


def test_magic_error(f: BufferedReader) -> None:
Expand All @@ -68,8 +68,8 @@ def test_magic_error(f: BufferedReader) -> None:
except Exception as e:
FAILED = True # pyright: ignore[reportConstantRedefinition]
print("fail")
print(" ", end="")
print(e)
print(" ", end="", file=sys.stderr)
print(e, file=sys.stderr)


def test_root_inode(volume: ext4.Volume) -> None:
Expand All @@ -82,8 +82,8 @@ def test_root_inode(volume: ext4.Volume) -> None:
except ext4.struct.ChecksumError as e:
FAILED = True # pyright: ignore[reportConstantRedefinition]
print("fail")
print(" ", end="")
print(e)
print(" ", end="", file=sys.stderr)
print(e, file=sys.stderr)


print("check ext4.Volume stream validation: ", end="")
Expand All @@ -98,8 +98,8 @@ def test_root_inode(volume: ext4.Volume) -> None:
except Exception as e:
FAILED = True # pyright: ignore[reportConstantRedefinition]
print("fail")
print(" ", end="")
print(e)
print(" ", end="", file=sys.stderr)
print(e, file=sys.stderr)

test_path_tuple("/", tuple())
test_path_tuple(b"/", tuple())
Expand Down Expand Up @@ -162,6 +162,10 @@ def test_root_inode(volume: ext4.Volume) -> None:
_ = b.seek(0)
_assert(f"b.read({x}) == {data[:x]}", lambda: b.seek(0) == 0 and b.read(x))

inode = cast(ext4.SymbolicLink, volume.inode_at("/symlink.txt"))
_assert("isinstance(inode, ext4.SymbolicLink)")
_assert('inode.readlink() == b"test.txt"', inode.readlink)
Comment thread
Eeems marked this conversation as resolved.

img_file = "test_htree.ext4"
print(f"Testing image: {img_file}")
with open(img_file, "rb") as f:
Expand Down
Loading