|
26 | 26 | import stat |
27 | 27 | import zlib |
28 | 28 | import mmap |
| 29 | +import hmac |
29 | 30 | import base64 |
30 | 31 | import shutil |
31 | 32 | import socket |
32 | 33 | import struct |
33 | 34 | import hashlib |
34 | 35 | import inspect |
35 | 36 | import datetime |
36 | | -import tempfile |
37 | 37 | import logging |
38 | 38 | import zipfile |
39 | 39 | import binascii |
@@ -344,8 +344,8 @@ def _is_printable(ch): |
344 | 344 | __use_ini_name__ = "archivefile.ini" |
345 | 345 | __use_json_file__ = False |
346 | 346 | __use_json_name__ = "archivefile.json" |
347 | | -if(__use_ini_file__ and __use_json_name__): |
348 | | - __use_json_name__ = False |
| 347 | +if(__use_ini_file__ and __use_json_file__): |
| 348 | + __use_json_file__ = False |
349 | 349 | if('PYARCHIVEFILE_CONFIG_FILE' in os.environ and os.path.exists(os.environ['PYARCHIVEFILE_CONFIG_FILE']) and __use_env_file__): |
350 | 350 | scriptconf = os.environ['PYARCHIVEFILE_CONFIG_FILE'] |
351 | 351 | else: |
@@ -600,10 +600,11 @@ def _get(section_dict, key, default=None): |
600 | 600 | 13: "junctions", |
601 | 601 | } |
602 | 602 |
|
603 | | -# Union categories defined by which base codes should populate them. |
604 | | -UNION_RULES = [ |
605 | | - ("links", set([FT["HARDLINK"], FT["SYMLINK"]])), |
606 | | - ("devices", set([FT["CHAR"], FT["BLOCK"]])), |
| 603 | +# Deterministic category order (handy for consistent output/printing). |
| 604 | +CATEGORY_ORDER = [ |
| 605 | + "files", "hardlinks", "symlinks", "characters", "blocks", |
| 606 | + "directories", "fifos", "sockets", "doors", "ports", |
| 607 | + "whiteouts", "sparsefiles", "junctions", "links", "devices" |
607 | 608 | ] |
608 | 609 |
|
609 | 610 | # Deterministic category order (handy for consistent output/printing). |
@@ -794,46 +795,6 @@ def VerbosePrintOutReturn(dbgtxt, outtype="log", dbgenable=True, dgblevel=20): |
794 | 795 | return dbgtxt |
795 | 796 |
|
796 | 797 |
|
797 | | -# --- Helpers --- |
798 | | -def _normalize_initial_data(data, isbytes, encoding): |
799 | | - """Return data in the correct type for write(): bytes (if isbytes) or text (if not).""" |
800 | | - if data is None: |
801 | | - return None |
802 | | - |
803 | | - if isbytes: |
804 | | - # Want bytes |
805 | | - if isinstance(data, bytes): |
806 | | - return data |
807 | | - # Py2: str is already bytes, unicode needs encode |
808 | | - if sys.version_info[0] == 2: |
809 | | - try: |
810 | | - unicode # noqa: F821 |
811 | | - except NameError: |
812 | | - pass |
813 | | - else: |
814 | | - if isinstance(data, unicode): # noqa: F821 |
815 | | - return data.encode(encoding) |
816 | | - # Py3 str -> encode |
817 | | - return str(data).encode(encoding) |
818 | | - else: |
819 | | - # Want text (unicode/str) |
820 | | - if sys.version_info[0] == 2: |
821 | | - try: |
822 | | - unicode # noqa: F821 |
823 | | - if isinstance(data, unicode): # noqa: F821 |
824 | | - return data |
825 | | - # bytes/str -> decode |
826 | | - return data.decode(encoding) if isinstance(data, str) else unicode(data) # noqa: F821 |
827 | | - except NameError: |
828 | | - # Very defensive; shouldn't happen |
829 | | - return data |
830 | | - else: |
831 | | - # Py3: want str |
832 | | - if isinstance(data, bytes): |
833 | | - return data.decode(encoding) |
834 | | - return str(data) |
835 | | - |
836 | | - |
837 | 798 | def _split_posix(path_text): |
838 | 799 | """Split POSIX paths regardless of OS; return list of components.""" |
839 | 800 | # Normalize leading './' |
@@ -1698,51 +1659,56 @@ def DetectTarBombArchiveFileArray(listarrayfiles, |
1698 | 1659 | } |
1699 | 1660 |
|
1700 | 1661 |
|
1701 | | -def _normalize_initial_data(data, isbytes, encoding): |
1702 | | - """ |
1703 | | - Coerce `data` to the correct type for the chosen mode: |
1704 | | - - bytes mode: return `bytes` (Py2: str; Py3: bytes) |
1705 | | - - text mode : return unicode/str (Py2: unicode; Py3: str) |
1706 | | - """ |
| 1662 | +def _as_bytes_like(data): |
| 1663 | + if isinstance(data, bytes): |
| 1664 | + return data |
| 1665 | + if isinstance(data, bytearray): |
| 1666 | + return bytes(data) |
| 1667 | + try: |
| 1668 | + mv = memoryview |
| 1669 | + except NameError: |
| 1670 | + mv = () |
| 1671 | + if mv and isinstance(data, mv): |
| 1672 | + return bytes(data) |
| 1673 | + return None |
| 1674 | + |
| 1675 | +def _normalize_initial_data(data, isbytes, encoding, *, errors="strict"): |
| 1676 | + """Return bytes (if isbytes) or text (unicode on Py2, str on Py3).""" |
1707 | 1677 | if data is None: |
1708 | 1678 | return None |
1709 | 1679 |
|
1710 | 1680 | if isbytes: |
1711 | | - # Need a byte sequence |
1712 | | - if isinstance(data, bytes): |
1713 | | - return data |
1714 | | - if isinstance(data, bytearray): |
1715 | | - return bytes(data) |
1716 | | - # memoryview may not exist on very old Py2 builds; guard dynamically |
1717 | | - mv_t = getattr(__builtins__, 'memoryview', type(None)) |
1718 | | - if isinstance(data, mv_t): |
1719 | | - return bytes(data) |
1720 | | - if isinstance(data, str): |
1721 | | - # Py2 str is already bytes; Py3 str must be encoded |
1722 | | - return data if PY2 else data.encode(encoding) |
1723 | | - if PY2 and isinstance(data, unicode): # noqa: F821 (unicode only in Py2) |
1724 | | - return data.encode(encoding) |
| 1681 | + b = _as_bytes_like(data) |
| 1682 | + if b is not None: |
| 1683 | + return b |
| 1684 | + if PY2: |
| 1685 | + if isinstance(data, unicode_type): |
| 1686 | + return data.encode(encoding, errors) |
| 1687 | + if isinstance(data, str): # Py2: str is already bytes-like |
| 1688 | + return data |
| 1689 | + else: |
| 1690 | + if isinstance(data, str): |
| 1691 | + return data.encode(encoding, errors) |
1725 | 1692 | raise TypeError("data must be bytes-like or text for isbytes=True (got %r)" % (type(data),)) |
1726 | 1693 | else: |
1727 | | - # Need text (unicode in Py2, str in Py3) |
1728 | 1694 | if PY2: |
1729 | | - if isinstance(data, unicode): # noqa: F821 |
| 1695 | + if isinstance(data, unicode_type): |
1730 | 1696 | return data |
| 1697 | + b = _as_bytes_like(data) |
| 1698 | + if b is not None: |
| 1699 | + return b.decode(encoding, errors) |
1731 | 1700 | if isinstance(data, str): |
1732 | | - return data.decode(encoding) |
1733 | | - if isinstance(data, bytearray): |
1734 | | - return bytes(data).decode(encoding) |
1735 | | - mv_t = getattr(__builtins__, 'memoryview', type(None)) |
1736 | | - if isinstance(data, mv_t): |
1737 | | - return bytes(data).decode(encoding) |
| 1701 | + return data.decode(encoding, errors) |
1738 | 1702 | raise TypeError("data must be unicode or bytes-like for text mode (got %r)" % (type(data),)) |
1739 | 1703 | else: |
1740 | 1704 | if isinstance(data, str): |
1741 | 1705 | return data |
1742 | | - if isinstance(data, (bytes, bytearray, memoryview)): |
1743 | | - return bytes(data).decode(encoding) |
| 1706 | + b = _as_bytes_like(data) |
| 1707 | + if b is not None: |
| 1708 | + return b.decode(encoding, errors) |
1744 | 1709 | raise TypeError("data must be str or bytes-like for text mode (got %r)" % (type(data),)) |
1745 | 1710 |
|
| 1711 | + |
1746 | 1712 | def MkTempFile(data=None, |
1747 | 1713 | inmem=True, |
1748 | 1714 | isbytes=True, |
|
0 commit comments