Skip to content

Commit da9d2ba

Browse files
committed
Fix endianness issues with s390x
1 parent 6e1871c commit da9d2ba

7 files changed

Lines changed: 42 additions & 38 deletions

File tree

‎ext4/blockdescriptor.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class BlockDescriptor(Ext4Struct):
3030
("bg_free_blocks_count_lo", c_uint16),
3131
("bg_free_inodes_count_lo", c_uint16),
3232
("bg_used_dirs_count_lo", c_uint16),
33-
("bg_flags", EXT4_BG),
33+
("bg_flags", EXT4_BG.basetype),
3434
("bg_exclude_bitmap_lo", c_uint32),
3535
("bg_block_bitmap_csum_lo", c_uint16),
3636
("bg_inode_bitmap_csum_lo", c_uint16),

‎ext4/directory.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,13 +73,13 @@ class DirectoryEntry2(DirectoryEntryBase):
7373
("inode", c_uint32),
7474
("rec_len", c_uint16),
7575
("name_len", c_uint8),
76-
("file_type", EXT4_FT),
76+
("file_type", EXT4_FT.basetype),
7777
("name", c_char * EXT4_NAME_LEN),
7878
]
7979

8080
@DirectoryEntryBase.is_fake_entry.getter
8181
def is_fake_entry(self) -> bool:
82-
file_type = assert_cast(self.file_type, EXT4_FT) # pyright: ignore[reportAny]
82+
file_type = EXT4_FT(self.file_type) # pyright: ignore[reportAny]
8383
return super().is_fake_entry or file_type == EXT4_FT.DIR_CSUM
8484

8585

‎ext4/enum.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ def __repr__(self) -> str:
4848
def TypedCEnumeration(_type: type["SimpleCData"]): # noqa: ANN201
4949
class CEnumeration(_type, metaclass=TypedEnumerationType(_type)): # pyright: ignore[reportGeneralTypeIssues, reportUntypedBaseClass] # noqa: ANN201,PLW1641,PLW1641
5050
_members_: dict[str, Any] = {} # pyright: ignore[reportExplicitAny]
51+
basetype: type["SimpleCData"] = _type
5152

5253
@override
5354
def __repr__(self) -> str:

‎ext4/htree.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class DXRootInfo(LittleEndianStructure):
8080
# _anonymous_ = ("reserved_zero")
8181
_fields_ = [
8282
("reserved_zero", c_uint32),
83-
("hash_version", DX_HASH),
83+
("hash_version", DX_HASH.basetype),
8484
("info_length", c_uint8),
8585
("indirect_levels", c_uint8),
8686
("unused_flags", c_uint8),

‎ext4/inode.py‎

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import warnings
77
from collections.abc import Generator
88
from ctypes import (
9-
BigEndianUnion,
109
LittleEndianStructure,
10+
LittleEndianUnion,
1111
c_uint16,
1212
c_uint32,
1313
sizeof,
@@ -103,7 +103,7 @@ class Masix1(LittleEndianStructure):
103103

104104

105105
@final
106-
class Osd1(BigEndianUnion):
106+
class Osd1(LittleEndianUnion):
107107
_pack_ = 1
108108
_fields_ = [
109109
("linux1", Linux1),
@@ -151,7 +151,7 @@ class Masix2(LittleEndianStructure):
151151

152152

153153
@final
154-
class Osd2(BigEndianUnion):
154+
class Osd2(LittleEndianUnion):
155155
_pack_ = 1
156156
_fields_ = [
157157
("linux2", Linux2),
@@ -165,7 +165,7 @@ class Inode(Ext4Struct):
165165
EXT2_GOOD_OLD_INODE_SIZE: int = 128
166166
_pack_ = 1 # pyright: ignore[reportUnannotatedClassAttribute]
167167
_fields_ = [ # pyright: ignore[reportUnannotatedClassAttribute]
168-
("i_mode", MODE),
168+
("i_mode", MODE.basetype),
169169
("i_uid", c_uint16),
170170
("i_size_lo", c_uint32),
171171
("i_atime", c_uint32),
@@ -175,7 +175,7 @@ class Inode(Ext4Struct):
175175
("i_gid", c_uint16),
176176
("i_links_count", c_uint16),
177177
("i_blocks_lo", c_uint32),
178-
("i_flags", EXT4_FL),
178+
("i_flags", EXT4_FL.basetype),
179179
("osd1", Osd1),
180180
("i_block", c_uint32 * 15),
181181
("i_generation", c_uint32),
@@ -199,9 +199,11 @@ def get_file_type(cls, volume: Volume, offset: int) -> EXT4_FT:
199199
_ = volume.seek(offset + Inode.i_mode.offset)
200200
file_type = cast(
201201
MODE,
202-
Inode.field_type("i_mode").from_buffer_copy( # pyright: ignore[reportAttributeAccessIssue, reportUnknownMemberType, reportOptionalMemberAccess]
202+
Inode.field_type("i_mode")
203+
.from_buffer_copy( # pyright: ignore[reportAttributeAccessIssue, reportUnknownMemberType, reportOptionalMemberAccess]
203204
volume.read(Inode.i_mode.size)
204205
)
206+
.value
205207
& 0xF000,
206208
)
207209
match file_type:
@@ -321,7 +323,7 @@ def seed(self) -> int:
321323

322324
@Ext4Struct.checksum.getter
323325
def checksum(self) -> int | None:
324-
s_creator_os: EXT4_OS = assert_cast(self.superblock.s_creator_os, EXT4_OS) # pyright: ignore[reportAny]
326+
s_creator_os: EXT4_OS = EXT4_OS(self.superblock.s_creator_os) # pyright: ignore[reportAny]
325327
if s_creator_os != EXT4_OS.LINUX:
326328
return None
327329

@@ -358,7 +360,7 @@ def checksum(self) -> int | None:
358360

359361
@Ext4Struct.expected_checksum.getter
360362
def expected_checksum(self) -> int | None:
361-
s_creator_os = assert_cast(self.superblock.s_creator_os, EXT4_OS) # pyright: ignore[reportAny]
363+
s_creator_os = EXT4_OS(self.superblock.s_creator_os) # pyright: ignore[reportAny]
362364
if s_creator_os != EXT4_OS.LINUX:
363365
return None
364366

@@ -378,7 +380,7 @@ def validate(self) -> None:
378380
self.tree.validate()
379381

380382
def has_flag(self, flag: EXT4_FL | int) -> bool:
381-
i_flags = assert_cast(self.i_flags, EXT4_FL) # pyright: ignore[reportAny]
383+
i_flags = EXT4_FL(self.i_flags) # pyright: ignore[reportAny]
382384
return (i_flags & flag) != 0
383385

384386
@property
@@ -610,7 +612,7 @@ def opendir(
610612
) -> Generator[tuple[DirectoryEntry | DirectoryEntry2, EXT4_FT], Any, None]: # pyright: ignore[reportExplicitAny]
611613
for dirent in self._opendir():
612614
if isinstance(dirent, DirectoryEntry2):
613-
file_type = assert_cast(dirent.file_type, EXT4_FT) # pyright: ignore[reportAny]
615+
file_type = EXT4_FT(dirent.file_type) # pyright: ignore[reportAny]
614616
if file_type == EXT4_FT.DIR_CSUM:
615617
continue
616618

‎ext4/superblock.py‎

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -59,21 +59,21 @@ class Superblock(Ext4Struct):
5959
("s_mnt_count", c_uint16),
6060
("s_max_mnt_count", c_uint16),
6161
("s_magic", c_uint16), # 0xEF53
62-
("s_state", EXT4_FS),
63-
("s_errors", EXT4_ERRORS),
62+
("s_state", EXT4_FS.basetype),
63+
("s_errors", EXT4_ERRORS.basetype),
6464
("s_minor_rev_level", c_uint16),
6565
("s_lastcheck", c_uint32),
6666
("s_checkinterval", c_uint32),
67-
("s_creator_os", EXT4_OS),
68-
("s_rev_level", EXT4_REV),
67+
("s_creator_os", EXT4_OS.basetype),
68+
("s_rev_level", EXT4_REV.basetype),
6969
("s_def_resuid", c_uint16),
7070
("s_def_resgid", c_uint16),
7171
("s_first_ino", c_uint32),
7272
("s_inode_size", c_uint16),
7373
("s_block_group_nr", c_uint16),
74-
("s_feature_compat", EXT4_FEATURE_COMPAT),
75-
("s_feature_incompat", EXT4_FEATURE_INCOMPAT),
76-
("s_feature_ro_compat", EXT4_FEATURE_RO_COMPAT),
74+
("s_feature_compat", EXT4_FEATURE_COMPAT.basetype),
75+
("s_feature_incompat", EXT4_FEATURE_INCOMPAT.basetype),
76+
("s_feature_ro_compat", EXT4_FEATURE_RO_COMPAT.basetype),
7777
("s_uuid", c_uint8 * 16),
7878
("s_volume_name", c_ubyte * 16),
7979
("s_last_mounted", c_ubyte * 64),
@@ -86,10 +86,10 @@ class Superblock(Ext4Struct):
8686
("s_journal_dev", c_uint32),
8787
("s_last_orphan", c_uint32),
8888
("s_hash_seed", c_uint32 * 4),
89-
("s_def_hash_version", DX_HASH),
89+
("s_def_hash_version", DX_HASH.basetype),
9090
("s_jnl_backup_type", c_uint8),
9191
("s_desc_size", c_uint16),
92-
("s_default_mount_opts", EXT4_DEFM),
92+
("s_default_mount_opts", EXT4_DEFM.basetype),
9393
("s_first_meta_bg", c_uint32),
9494
("s_mkfs_time", c_uint32),
9595
("s_jnl_blocks", c_uint32 * 17),
@@ -98,13 +98,13 @@ class Superblock(Ext4Struct):
9898
("s_free_blocks_count_hi", c_uint32),
9999
("s_min_extra_isize", c_uint16),
100100
("s_want_extra_isize", c_uint16),
101-
("s_flags", EXT2_FLAGS),
101+
("s_flags", EXT2_FLAGS.basetype),
102102
("s_raid_stride", c_uint16),
103103
("s_mmp_interval", c_uint16),
104104
("s_mmp_block", c_uint64),
105105
("s_raid_stripe_width", c_uint32),
106106
("s_log_groups_per_flex", c_uint8),
107-
("s_checksum_type", EXT4_CHKSUM),
107+
("s_checksum_type", EXT4_CHKSUM.basetype),
108108
("s_reserved_pad", c_uint16),
109109
("s_kbytes_written", c_uint64),
110110
("s_snapshot_inum", c_uint32),
@@ -122,12 +122,12 @@ class Superblock(Ext4Struct):
122122
("s_last_error_line", c_uint32),
123123
("s_last_error_block", c_uint64),
124124
("s_last_error_func", c_uint8 * 32),
125-
("s_mount_opts", EXT4_MOUNT * 64), # pyright: ignore[reportOperatorIssue]
125+
("s_mount_opts", EXT4_MOUNT.basetype * 64), # pyright: ignore[reportOperatorIssue]
126126
("s_usr_quota_inum", c_uint32),
127127
("s_grp_quota_inum", c_uint32),
128128
("s_overhead_blocks", c_uint32),
129129
("s_backup_bgs", c_uint32 * 2),
130-
("s_encrypt_algos", FS_ENCRYPTION_MODE * 4), # pyright: ignore[reportOperatorIssue]
130+
("s_encrypt_algos", FS_ENCRYPTION_MODE.basetype * 4), # pyright: ignore[reportOperatorIssue]
131131
("s_encrypt_pw_salt", c_uint8 * 16),
132132
("s_lpf_ino", c_uint32),
133133
("s_prj_quota_inum", c_uint32),
@@ -206,21 +206,15 @@ def checksum(self) -> int | None:
206206

207207
@property
208208
def feature_incompat(self) -> EXT4_FEATURE_INCOMPAT:
209-
s_feature_incompat = assert_cast(self.s_feature_incompat, EXT4_FEATURE_INCOMPAT) # pyright: ignore[reportAny]
210-
return s_feature_incompat
209+
return EXT4_FEATURE_INCOMPAT(self.s_feature_incompat) # pyright: ignore[reportAny]
211210

212211
@property
213212
def feature_compat(self) -> EXT4_FEATURE_COMPAT:
214-
s_feature_compat = assert_cast(self.s_feature_compat, EXT4_FEATURE_COMPAT) # pyright: ignore[reportAny]
215-
return s_feature_compat
213+
return EXT4_FEATURE_COMPAT(self.s_feature_compat) # pyright: ignore[reportAny]
216214

217215
@property
218216
def feature_ro_compat(self) -> EXT4_FEATURE_RO_COMPAT:
219-
s_feature_ro_compat = assert_cast(
220-
self.s_feature_ro_compat, # pyright: ignore[reportAny]
221-
EXT4_FEATURE_RO_COMPAT,
222-
)
223-
return s_feature_ro_compat
217+
return EXT4_FEATURE_RO_COMPAT(self.s_feature_ro_compat) # pyright: ignore[reportAny]
224218

225219
@property
226220
def seed(self) -> int:

‎test.py‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,10 @@ def test_root_inode(volume: ext4.Volume) -> None:
189189
htree = volume.root.htree
190190
_assert("htree is not None")
191191
if htree is not None:
192-
_assert("isinstance(htree.dot, ext4.DotDirectoryEntry2)", lambda: htree.dot) # pyright: ignore[reportOptionalMemberAccess, reportAny]
192+
_assert(
193+
"isinstance(htree.dot, ext4.DotDirectoryEntry2)",
194+
lambda: htree.dot, # pyright: ignore[reportOptionalMemberAccess, reportAny]
195+
)
193196
_assert(
194197
"isinstance(htree.dotdot, ext4.DotDirectoryEntry2)",
195198
lambda: htree.dotdot, # pyright: ignore[reportOptionalMemberAccess, reportAny]
@@ -208,7 +211,11 @@ def test_root_inode(volume: ext4.Volume) -> None:
208211

209212
dx_root_info = htree.dx_root_info # pyright: ignore[reportAny]
210213
_assert(
211-
"isinstance(dx_root_info.hash_version, ext4.DX_HASH)",
214+
"isinstance(dx_root_info.hash_version, int)",
215+
lambda: dx_root_info.hash_version, # pyright: ignore[reportAny]
216+
)
217+
_assert(
218+
"ext4.DX_HASH(dx_root_info.hash_version)",
212219
lambda: dx_root_info.hash_version, # pyright: ignore[reportAny]
213220
)
214221
_assert("dx_root_info.info_length == 8", lambda: dx_root_info.info_length) # pyright: ignore[reportAny]

0 commit comments

Comments
 (0)