Skip to content

Commit 2add115

Browse files
authored
Merge pull request #9 from MAK-Relic-Tool/fix-#39
Fix EssenceFS not respecting `//` seperator when parsing paths
2 parents 10af75c + aab3594 commit 2add115

4 files changed

Lines changed: 116 additions & 4 deletions

File tree

src/relic/sga/core/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
"""
44
from relic.sga.core.definitions import Version, MagicWord, StorageType, VerificationType
55

6-
__version__ = "1.0.0"
6+
__version__ = "1.0.1"

src/relic/sga/core/filesystem.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,8 +250,8 @@ def _make_dir_entry(
250250
def validatepath(self, path: str) -> str:
251251
if ":" in path:
252252
parts = path.split(":", 1)
253-
if parts[0][0] == "/":
254-
parts[0] = parts[0][1:]
253+
if parts[0].replace("\\", "/")[0] == "/":
254+
parts[0] = parts[0].replace("\\", "/")[1:]
255255
if parts[0] != self.alias:
256256
raise fs.errors.InvalidPath(
257257
path,
@@ -260,7 +260,7 @@ def validatepath(self, path: str) -> str:
260260
fixed_path = parts[1]
261261
else:
262262
fixed_path = path
263-
return super().validatepath(fixed_path)
263+
return super().validatepath(fixed_path).replace("\\", "/")
264264

265265
def setinfo(self, path: str, info: Mapping[str, Mapping[str, object]]) -> None:
266266
_path = self.validatepath(path)

src/relic/sga/core/serialization.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,9 @@ def disassemble_folder(self, folder_fs: FS, path: str) -> FolderDef:
519519

520520
folder_name = str(path).split(":", 1)[-1] # Strip 'alias:' from path
521521

522+
if folder_name[0] == "/":
523+
folder_name = folder_name[1:] # strip leading '/'
524+
522525
folder_def.name_pos = _get_or_write_name(
523526
folder_name, self.name_stream, self.flat_names
524527
)

tests/issues/test_issue_39.py

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
"""
2+
TestCases for 'EssenceDriveFS not respecting // separator'
3+
https://github.com/MAK-Relic-Tool/Issue-Tracker/issues/39
4+
"""
5+
import zlib
6+
from contextlib import contextmanager
7+
8+
import fs
9+
from fs.base import FS
10+
from fs.memoryfs import MemoryFS
11+
12+
from relic.sga.core import StorageType
13+
from relic.sga.core.filesystem import EssenceFS
14+
15+
16+
@contextmanager
17+
def _generate_fake_osfs() -> FS:
18+
raw_text = b"""Ready to unleash 11 barrels of lead.
19+
Where's that artillery?!?!
20+
Orks are da biggust and da strongest.
21+
Fix bayonets!
22+
Fear me, but follow!
23+
Call for an earth-shaker?
24+
My mind is too weary to fight on...
25+
We'll be off as soon as the fuel arrives.
26+
Where are those tech priests.
27+
Fire until they see the glow of our barrels!"""
28+
29+
comp_text = zlib.compress(raw_text)
30+
31+
with MemoryFS() as fs:
32+
with fs.makedir("/samples") as samples_folder:
33+
with samples_folder.makedir("/strings") as strings_folders:
34+
with strings_folders.openbin("buffer.txt", "wb") as file:
35+
file.write(comp_text)
36+
with strings_folders.openbin("stream.txt", "wb") as file:
37+
file.write(comp_text)
38+
with strings_folders.openbin("store.txt", "wb") as file:
39+
file.write(raw_text)
40+
yield fs
41+
42+
43+
_CHUNK_SIZE = 1024 * 1024 * 16 # 16 MiB
44+
45+
46+
def _pack_fake_osfs(osfs: FS, name: str) -> EssenceFS:
47+
# Create 'SGA'
48+
sga = EssenceFS()
49+
sga.setmeta(
50+
{
51+
"name": name, # Specify name of archive
52+
"header_md5": "0"
53+
* 16, # Must be present due to a bug, recalculated when packed
54+
"file_md5": "0"
55+
* 16, # Must be present due to a bug, recalculated when packed
56+
},
57+
"essence",
58+
)
59+
60+
alias = "test"
61+
sga_drive = None # sga.create_drive(alias)
62+
for path in osfs.walk.files():
63+
if (
64+
sga_drive is None
65+
): # Lazily create drive, to avoid empty drives from being created
66+
sga_drive = sga.create_drive(alias)
67+
68+
if "stream" in path:
69+
storage = StorageType.STREAM_COMPRESS
70+
elif "buffer" in path:
71+
storage = StorageType.BUFFER_COMPRESS
72+
else:
73+
storage = StorageType.STORE
74+
75+
with osfs.openbin(path, "r") as unpacked_file:
76+
parent, file = fs.path.split(path)
77+
with sga_drive.makedirs(parent, recreate=True) as folder:
78+
with folder.openbin(file, "w") as packed_file:
79+
while True:
80+
buffer = unpacked_file.read(_CHUNK_SIZE)
81+
if len(buffer) == 0:
82+
break
83+
packed_file.write(buffer)
84+
sga_drive.setinfo(path, {"essence": {"storage_type": storage}})
85+
return sga
86+
87+
88+
def _check_path(sga: EssenceFS, path: str):
89+
left_sep = path.replace("\\", "/")
90+
right_sep = path.replace("/", "\\")
91+
92+
info = sga.getinfo(path)
93+
l_info = sga.getinfo(left_sep)
94+
r_info = sga.getinfo(right_sep)
95+
96+
assert info == l_info
97+
assert l_info == r_info
98+
99+
100+
def test_fix_39():
101+
with _generate_fake_osfs() as osfs:
102+
sga = _pack_fake_osfs(osfs, "Test Archive")
103+
for root, folders, files in sga.walk():
104+
_check_path(sga, root)
105+
# for folder in folders
106+
# folders are checked when we walk into them
107+
for file in files:
108+
full_path = fs.path.join(root, file.name)
109+
_check_path(sga, full_path)

0 commit comments

Comments
 (0)