@@ -93,18 +93,16 @@ def _normalize_algo(algo):
9393 return 'auto'
9494 return a
9595
96- def _normalize_ver_digits (ver_text ):
96+ def _normalize_ver_digits (ver ):
9797 """
98- Make the on-disk version match Archive's strict header check:
99- - remove dots
100- - strip leading zeros by int() cast when numeric
101- Falls back to the raw digits if not purely numeric.
98+ Accepts '001', '1', or int-like; returns a canonical zero-padded string
99+ (e.g., '001'). Adjust this to whatever your writer emits in the global header.
102100 """
103- raw = ver_text . replace ( "." , "" )
104- try :
105- return str (int ( raw )) # "001" -> "1"
106- except ValueError :
107- return raw # keep as-is if not numeric
101+ if ver is None :
102+ return "001"
103+ s = str (ver ). replace ( '.' , '' )
104+ # If your header stores zero-padded 3 digits, enforce that here :
105+ return "{:0>3}" . format ( int ( s )) if s . isdigit () else s
108106
109107def _compress_bytes (data , algo = 'none' , level = None ):
110108 """Return (stored_bytes, used_algo)."""
@@ -696,6 +694,14 @@ def _parse_global_header(fp, formatspecs, skipchecksum=False):
696694 checksumtype = _read_cstring (fp , delim ).decode ('UTF-8' )
697695 _header_cs = _read_cstring (fp , delim ).decode ('UTF-8' )
698696 return {'fencoding' : fencoding , 'fnumfiles' : fnumfiles , 'fostype' : fostype ,
697+ # --- Strict check for magic+version against formatspecs ---
698+ exp_magic = formatspecs .get ('format_magic' , '' )
699+ exp_ver = _normalize_ver_digits (_ver_digits (formatspecs .get ('format_ver' , '001' )))
700+ expected_magicver = exp_magic + exp_ver
701+ if str (magicver ) != str (expected_magicver ):
702+ raise ValueError (
703+ "Bad archive header: magic/version mismatch (got {!r}, expected {!r})" .format (magicver , expected_magicver )
704+ )
699705 'fextradata' : extras , 'fchecksumtype' : checksumtype ,
700706 'ffilelist' : [], 'fformatspecs' : formatspecs }
701707
0 commit comments