PyCatFile 0.28.2__tar.gz → 0.28.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pycatfile-0.28.2 → pycatfile-0.28.4}/PKG-INFO +1 -1
- {pycatfile-0.28.2 → pycatfile-0.28.4}/PyCatFile.egg-info/PKG-INFO +1 -1
- {pycatfile-0.28.2 → pycatfile-0.28.4}/catfile.py +1 -1
- {pycatfile-0.28.2 → pycatfile-0.28.4}/catfile_py3.py +1 -1
- {pycatfile-0.28.2 → pycatfile-0.28.4}/pycatfile.py +59 -21
- {pycatfile-0.28.2 → pycatfile-0.28.4}/pycatfile_py3.py +593 -195
- {pycatfile-0.28.2 → pycatfile-0.28.4}/pyproject.toml +1 -1
- {pycatfile-0.28.2 → pycatfile-0.28.4}/LICENSE +0 -0
- {pycatfile-0.28.2 → pycatfile-0.28.4}/PyCatFile.egg-info/SOURCES.txt +0 -0
- {pycatfile-0.28.2 → pycatfile-0.28.4}/PyCatFile.egg-info/dependency_links.txt +0 -0
- {pycatfile-0.28.2 → pycatfile-0.28.4}/PyCatFile.egg-info/top_level.txt +0 -0
- {pycatfile-0.28.2 → pycatfile-0.28.4}/PyCatFile.egg-info/zip-safe +0 -0
- {pycatfile-0.28.2 → pycatfile-0.28.4}/README.md +0 -0
- {pycatfile-0.28.2 → pycatfile-0.28.4}/setup.cfg +0 -0
- {pycatfile-0.28.2 → pycatfile-0.28.4}/setup.py +0 -0
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
Copyright 2018-2026 Game Maker 2k - http://intdb.sourceforge.net/
|
|
15
15
|
Copyright 2018-2026 Kazuki Przyborowski - https://github.com/KazukiPrzyborowski
|
|
16
16
|
|
|
17
|
-
$FileInfo: catfile.py - Last Update: 2/
|
|
17
|
+
$FileInfo: catfile.py - Last Update: 2/6/2026 Ver. 0.28.4 RC 1 - Author: cooldude2k $
|
|
18
18
|
'''
|
|
19
19
|
|
|
20
20
|
from __future__ import absolute_import, division, print_function, unicode_literals, generators, with_statement, nested_scopes
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
Copyright 2018-2026 Game Maker 2k - http://intdb.sourceforge.net/
|
|
14
14
|
Copyright 2018-2026 Kazuki Przyborowski - https://github.com/KazukiPrzyborowski
|
|
15
15
|
|
|
16
|
-
$FileInfo: catfile_py3.py - Last Update: 2/
|
|
16
|
+
$FileInfo: catfile_py3.py - Last Update: 2/6/2026 Ver. 0.28.4 RC 1 - Author: cooldude2k $
|
|
17
17
|
'''
|
|
18
18
|
|
|
19
19
|
from __future__ import annotations
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
Copyright 2018-2026 Game Maker 2k - http://intdb.sourceforge.net/
|
|
15
15
|
Copyright 2018-2026 Kazuki Przyborowski - https://github.com/KazukiPrzyborowski
|
|
16
16
|
|
|
17
|
-
$FileInfo: pycatfile.py - Last Update: 2/
|
|
17
|
+
$FileInfo: pycatfile.py - Last Update: 2/6/2026 Ver. 0.28.4 RC 1 - Author: cooldude2k $
|
|
18
18
|
'''
|
|
19
19
|
|
|
20
20
|
from __future__ import absolute_import, division, print_function, unicode_literals, generators, with_statement, nested_scopes
|
|
@@ -661,12 +661,12 @@ __project__ = __program_name__
|
|
|
661
661
|
__program_alt_name__ = __program_name__
|
|
662
662
|
__project_url__ = "https://github.com/GameMaker2k/PyCatFile"
|
|
663
663
|
__project_release_url__ = __project_url__+"/releases/latest"
|
|
664
|
-
__version_info__ = (0, 28,
|
|
665
|
-
__version_date_info__ = (2026, 2,
|
|
664
|
+
__version_info__ = (0, 28, 4, "RC 1", 1)
|
|
665
|
+
__version_date_info__ = (2026, 2, 6, "RC 1", 1)
|
|
666
666
|
__version_date__ = str(__version_date_info__[0]) + "." + str(
|
|
667
667
|
__version_date_info__[1]).zfill(2) + "." + str(__version_date_info__[2]).zfill(2)
|
|
668
668
|
__revision__ = __version_info__[3]
|
|
669
|
-
__revision_id__ = "$Id:
|
|
669
|
+
__revision_id__ = "$Id: a87c7aadb79d3eebf05d8e955d7294c74e99a96e $"
|
|
670
670
|
if(__version_info__[4] is not None):
|
|
671
671
|
__version_date_plusrc__ = __version_date__ + \
|
|
672
672
|
"-" + str(__version_date_info__[4])
|
|
@@ -4646,7 +4646,7 @@ def ReadFileHeaderDataWoSize(fp, delimiter=_default_delim(None)):
|
|
|
4646
4646
|
return first_two + headerdata
|
|
4647
4647
|
|
|
4648
4648
|
|
|
4649
|
-
def ReadFileHeaderDataWithContent(fp, listonly=False, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__, saltkey=None):
|
|
4649
|
+
def ReadFileHeaderDataWithContent(fp, listonly=False, contentasfile=False, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__, saltkey=None):
|
|
4650
4650
|
if(not hasattr(fp, "read")):
|
|
4651
4651
|
return False
|
|
4652
4652
|
delimiter = formatspecs['format_delimiter']
|
|
@@ -4663,15 +4663,41 @@ def ReadFileHeaderDataWithContent(fp, listonly=False, uncompress=True, skipcheck
|
|
|
4663
4663
|
fcs = HeaderOut[-2].lower()
|
|
4664
4664
|
fccs = HeaderOut[-1].lower()
|
|
4665
4665
|
fsize = int(HeaderOut[7], 16)
|
|
4666
|
-
fcompression = HeaderOut[
|
|
4667
|
-
fcsize = int(HeaderOut[
|
|
4668
|
-
fseeknextfile = HeaderOut[
|
|
4669
|
-
fjsontype = HeaderOut[
|
|
4670
|
-
fjsonlen = int(HeaderOut[
|
|
4671
|
-
fjsonsize = int(HeaderOut[
|
|
4672
|
-
fjsonchecksumtype = HeaderOut[
|
|
4673
|
-
fjsonchecksum = HeaderOut[
|
|
4674
|
-
|
|
4666
|
+
fcompression = HeaderOut[17]
|
|
4667
|
+
fcsize = int(HeaderOut[18], 16)
|
|
4668
|
+
fseeknextfile = HeaderOut[28]
|
|
4669
|
+
fjsontype = HeaderOut[29]
|
|
4670
|
+
fjsonlen = int(HeaderOut[30], 16)
|
|
4671
|
+
fjsonsize = int(HeaderOut[31], 16)
|
|
4672
|
+
fjsonchecksumtype = HeaderOut[32]
|
|
4673
|
+
fjsonchecksum = HeaderOut[33]
|
|
4674
|
+
fextrasize = int(HeaderOut[34], 16)
|
|
4675
|
+
fextrafields = int(HeaderOut[35], 16)
|
|
4676
|
+
fextrafieldslist = []
|
|
4677
|
+
extrastart = 36
|
|
4678
|
+
extraend = extrastart + fextrafields
|
|
4679
|
+
while(extrastart < extraend):
|
|
4680
|
+
fextrafieldslist.append(HeaderOut[extrastart])
|
|
4681
|
+
extrastart = extrastart + 1
|
|
4682
|
+
fvendorfieldslist = []
|
|
4683
|
+
fvendorfields = 0;
|
|
4684
|
+
if((len(HeaderOut) - 4)>extraend):
|
|
4685
|
+
extrastart = extraend
|
|
4686
|
+
extraend = len(HeaderOut) - 4
|
|
4687
|
+
while(extrastart < extraend):
|
|
4688
|
+
fvendorfieldslist.append(HeaderOut[extrastart])
|
|
4689
|
+
extrastart = extrastart + 1
|
|
4690
|
+
fvendorfields = fvendorfields + 1
|
|
4691
|
+
if(fextrafields==1):
|
|
4692
|
+
try:
|
|
4693
|
+
fextrafieldslist = json.loads(base64.b64decode(fextrafieldslist[0]).decode("UTF-8"))
|
|
4694
|
+
fextrafields = len(fextrafieldslist)
|
|
4695
|
+
except (binascii.Error, json.decoder.JSONDecodeError, UnicodeDecodeError):
|
|
4696
|
+
try:
|
|
4697
|
+
fextrafieldslist = json.loads(fextrafieldslist[0])
|
|
4698
|
+
except (binascii.Error, json.decoder.JSONDecodeError, UnicodeDecodeError):
|
|
4699
|
+
pass
|
|
4700
|
+
fjstart = fp.tell()
|
|
4675
4701
|
if(fjsontype=="json"):
|
|
4676
4702
|
fjsoncontent = {}
|
|
4677
4703
|
fprejsoncontent = fp.read(fjsonsize).decode("UTF-8")
|
|
@@ -4738,31 +4764,37 @@ def ReadFileHeaderDataWithContent(fp, listonly=False, uncompress=True, skipcheck
|
|
|
4738
4764
|
except (binascii.Error, json.decoder.JSONDecodeError, UnicodeDecodeError):
|
|
4739
4765
|
pass
|
|
4740
4766
|
fp.seek(len(delimiter), 1)
|
|
4767
|
+
fjend = fp.tell() - 1
|
|
4741
4768
|
jsonfcs = GetFileChecksum(fprejsoncontent, fjsonchecksumtype, True, formatspecs, saltkey)
|
|
4742
4769
|
if(not CheckChecksums(fjsonchecksum, jsonfcs) and not skipchecksum):
|
|
4743
4770
|
VerbosePrintOut("File JSON Data Checksum Error with file " +
|
|
4744
4771
|
fname + " at offset " + str(fheaderstart))
|
|
4745
4772
|
VerbosePrintOut("'" + fjsonchecksum + "' != " + "'" + jsonfcs + "'")
|
|
4746
4773
|
return False
|
|
4747
|
-
|
|
4774
|
+
fcs = HeaderOut[-2].lower()
|
|
4775
|
+
fccs = HeaderOut[-1].lower()
|
|
4748
4776
|
newfcs = GetHeaderChecksum(HeaderOut[:-2], HeaderOut[-4].lower(), True, formatspecs, saltkey)
|
|
4749
|
-
HeaderOut.append(fjsoncontent)
|
|
4750
4777
|
if(fcs != newfcs and not skipchecksum):
|
|
4751
4778
|
VerbosePrintOut("File Header Checksum Error with file " +
|
|
4752
4779
|
fname + " at offset " + str(fheaderstart))
|
|
4753
4780
|
VerbosePrintOut("'" + fcs + "' != " + "'" + newfcs + "'")
|
|
4754
4781
|
return False
|
|
4782
|
+
fhend = fp.tell() - 1
|
|
4783
|
+
fcontentstart = fp.tell()
|
|
4755
4784
|
fcontents = MkTempFile()
|
|
4785
|
+
pyhascontents = False
|
|
4756
4786
|
if(fsize > 0 and not listonly):
|
|
4757
4787
|
if(fcompression == "none" or fcompression == "" or fcompression == "auto"):
|
|
4758
4788
|
fcontents.write(fp.read(fsize))
|
|
4759
4789
|
else:
|
|
4760
4790
|
fcontents.write(fp.read(fcsize))
|
|
4791
|
+
pyhascontents = True
|
|
4761
4792
|
elif(fsize > 0 and listonly):
|
|
4762
4793
|
if(fcompression == "none" or fcompression == "" or fcompression == "auto"):
|
|
4763
4794
|
fp.seek(fsize, 1)
|
|
4764
4795
|
else:
|
|
4765
4796
|
fp.seek(fcsize, 1)
|
|
4797
|
+
pyhascontents = False
|
|
4766
4798
|
fcontents.seek(0, 0)
|
|
4767
4799
|
newfccs = GetFileChecksum(fcontents, HeaderOut[-3].lower(), False, formatspecs, saltkey)
|
|
4768
4800
|
fcontents.seek(0, 0)
|
|
@@ -4776,12 +4808,15 @@ def ReadFileHeaderDataWithContent(fp, listonly=False, uncompress=True, skipcheck
|
|
|
4776
4808
|
else:
|
|
4777
4809
|
fcontents.seek(0, 0)
|
|
4778
4810
|
if(uncompress):
|
|
4779
|
-
cfcontents = UncompressFileAlt(
|
|
4811
|
+
cfcontents = UncompressFileAlt(
|
|
4812
|
+
fcontents, formatspecs)
|
|
4780
4813
|
cfcontents.seek(0, 0)
|
|
4781
4814
|
fcontents = MkTempFile()
|
|
4782
4815
|
shutil.copyfileobj(cfcontents, fcontents, length=__filebuff_size__)
|
|
4783
4816
|
cfcontents.close()
|
|
4784
4817
|
fcontents.seek(0, 0)
|
|
4818
|
+
fccs = GetFileChecksum(fcontents, HeaderOut[-3].lower(), False, formatspecs, saltkey)
|
|
4819
|
+
fcontentend = fp.tell()
|
|
4785
4820
|
if(re.findall("^\\+([0-9]+)", fseeknextfile)):
|
|
4786
4821
|
fseeknextasnum = int(fseeknextfile.replace("+", ""))
|
|
4787
4822
|
if(abs(fseeknextasnum) == 0):
|
|
@@ -4799,6 +4834,9 @@ def ReadFileHeaderDataWithContent(fp, listonly=False, uncompress=True, skipcheck
|
|
|
4799
4834
|
fp.seek(fseeknextasnum, 0)
|
|
4800
4835
|
else:
|
|
4801
4836
|
return False
|
|
4837
|
+
fcontents.seek(0, 0)
|
|
4838
|
+
if(not contentasfile):
|
|
4839
|
+
fcontents = fcontents.read()
|
|
4802
4840
|
HeaderOut.append(fcontents)
|
|
4803
4841
|
return HeaderOut
|
|
4804
4842
|
|
|
@@ -5247,7 +5285,7 @@ def ReadFileHeaderDataWithContentToList(fp, listonly=False, contentasfile=False,
|
|
|
5247
5285
|
return outlist
|
|
5248
5286
|
|
|
5249
5287
|
|
|
5250
|
-
def ReadFileDataWithContent(fp, filestart=0, listonly=False, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__, saltkey=None):
|
|
5288
|
+
def ReadFileDataWithContent(fp, filestart=0, listonly=False, contentasfile=False, uncompress=True, skipchecksum=False, formatspecs=__file_format_dict__, saltkey=None):
|
|
5251
5289
|
if(not hasattr(fp, "read")):
|
|
5252
5290
|
return False
|
|
5253
5291
|
delimiter = formatspecs['format_delimiter']
|
|
@@ -5285,8 +5323,8 @@ def ReadFileDataWithContent(fp, filestart=0, listonly=False, uncompress=True, sk
|
|
|
5285
5323
|
"'" + newfcs + "'")
|
|
5286
5324
|
return False
|
|
5287
5325
|
fnumfiles = int(inheader[8], 16)
|
|
5288
|
-
outfseeknextfile =
|
|
5289
|
-
fjsonsize = int(
|
|
5326
|
+
outfseeknextfile = inheader[9]
|
|
5327
|
+
fjsonsize = int(inheader[12], 16)
|
|
5290
5328
|
fjsonchecksumtype = inheader[13]
|
|
5291
5329
|
fjsonchecksum = inheader[14]
|
|
5292
5330
|
fp.read(fjsonsize)
|
|
@@ -5311,7 +5349,7 @@ def ReadFileDataWithContent(fp, filestart=0, listonly=False, uncompress=True, sk
|
|
|
5311
5349
|
countnum = 0
|
|
5312
5350
|
flist = []
|
|
5313
5351
|
while(countnum < fnumfiles):
|
|
5314
|
-
HeaderOut = ReadFileHeaderDataWithContent(fp, listonly, uncompress, skipchecksum, formatspecs, saltkey)
|
|
5352
|
+
HeaderOut = ReadFileHeaderDataWithContent(fp, listonly, contentasfile, uncompress, skipchecksum, formatspecs, saltkey)
|
|
5315
5353
|
if(len(HeaderOut) == 0):
|
|
5316
5354
|
break
|
|
5317
5355
|
flist.append(HeaderOut)
|