def load_module_from_file_object(fp,
                                 filename="<unknown>",
                                 code_objects=None,
                                 fast_load=False,
                                 get_code=True):
    """load a module from a file object without importing it.

    See :func:load_module for a list of return values.
    """

    if code_objects is None:
        code_objects = {}

    timestamp = 0
    try:
        magic = fp.read(4)
        magic_int = magic2int(magic)

        # For reasons I don't understand, PyPy 3.2 stores a magic
        # of '0'...  The two values below are for Python 2.x and 3.x respectively
        if magic[0:1] in ["0", b"0"]:
            magic = int2magic(3180 + 7)

        try:
            # FIXME: use the internal routine below
            float_version = magic_int2float(magic_int)
        except KeyError:
            if magic_int in (2657, 22138):
                raise ImportError(
                    "This smells like Pyston which is not supported.")

            if len(magic) >= 2:
                raise ImportError(
                    "Unknown magic number %s in %s" %
                    (ord(magic[0:1]) + 256 * ord(magic[1:2]), filename))
            else:
                raise ImportError("Bad magic number: '%s'" % magic)

        if magic_int in (
                3010,
                3020,
                3030,
                3040,
                3050,
                3060,
                3061,
                3071,
                3361,
                3091,
                3101,
                3103,
                3141,
                3270,
                3280,
                3290,
                3300,
                3320,
                3330,
                3371,
                62071,
                62071,
                62081,
                62091,
                62092,
                62111,
        ):
            raise ImportError("%s is interim Python %s (%d) bytecode which is "
                              "not supported.\nFinal released versions are "
                              "supported." %
                              (filename, versions[magic], magic2int(magic)))
        elif magic_int == 62135:
            fp.seek(0)
            return fix_dropbox_pyc(fp)
        elif magic_int == 62215:
            raise ImportError(
                "%s is a dropbox-hacked Python %s (bytecode %d).\n"
                "See https://github.com/kholia/dedrop for how to "
                "decrypt." % (filename, versions[magic], magic2int(magic)))

        try:
            # print version
            my_magic_int = PYTHON_MAGIC_INT
            magic_int = magic2int(magic)
            version = magic_int2float(magic_int)

            timestamp = None
            source_size = None
            sip_hash = None

            ts = fp.read(4)
            if version >= 3.7:
                # PEP 552. https://www.python.org/dev/peps/pep-0552/
                pep_bits = ts[-1]
                if PYTHON_VERSION <= 2.7:
                    pep_bits = ord(pep_bits)
                if (pep_bits & 1) or magic_int == 3393:  # 3393 is 3.7.0beta3
                    # SipHash
                    sip_hash = unpack("<Q", fp.read(8))[0]
                else:
                    # Uses older-style timestamp and size
                    timestamp = unpack("<I", fp.read(4))[0]  # pep552_bits
                    source_size = unpack("<I", fp.read(4))[0]  # size mod 2**32
                    pass
            else:
                timestamp = unpack("<I", ts)[0]
                # Note: a higher magic number doesn't necessarily mean a later
                # release.  At Python 3.0 the magic number decreased
                # significantly. Hence the range below. Also note inclusion of
                # the size info, occurred within a Python major/minor
                # release. Hence the test on the magic value rather than
                # PYTHON_VERSION, although PYTHON_VERSION would probably work.
                if ((3200 <= magic_int < 20121) and version >= 1.5
                        or magic_int in IS_PYPY3):
                    source_size = unpack("<I", fp.read(4))[0]  # size mod 2**32

            if get_code:
                if my_magic_int == magic_int:
                    bytecode = fp.read()
                    co = marshal.loads(bytecode)
                elif fast_load:
                    co = xdis.marsh.load(fp, magicint2version[magic_int])
                else:
                    co = xdis.unmarshal.load_code(fp, magic_int, code_objects)
                pass
            else:
                co = None
        except:
            kind, msg = sys.exc_info()[0:2]
            import traceback

            traceback.print_exc()
            raise ImportError("Ill-formed bytecode file %s\n%s; %s" %
                              (filename, kind, msg))

    finally:
        fp.close()

    return (
        float_version,
        timestamp,
        magic_int,
        co,
        is_pypy(magic_int),
        source_size,
        sip_hash,
    )
Beispiel #2
0
def load_module(filename, code_objects=None, fast_load=False,
                get_code=True):
    """load a module without importing it.
    load_module(filename: string): version, magic_int, code_object

    filename:	name of file containing Python byte-code object
                (normally a .pyc)

    code_object: code_object from this file
    version: Python major/minor value e.g. 2.7. or 3.4
    magic_int: more specific than version. The actual byte code version of the
               code object

    Parsing the  code object takes a bit of parsing time, but
    sometimes all you want is the module info, time string, code size,
    python version, etc. For that, set get_code=False.
    """
    if code_objects is None:
        code_objects = {}

    timestamp = 0
    fp = open(filename, 'rb')
    try:
        magic = fp.read(4)
        magic_int = magics.magic2int(magic)

        # For reasons I don't understand PyPy 3.2 stores a magic
        # of '0'...  The two values below are for Python 2.x and 3.x respectively
        if magic[0:1] in ['0', b'0']:
            magic = magics.int2magic(3180+7)

        try:
            version = float(magics.versions[magic][:3])
        except KeyError:
            if len(magic) >= 2:
                raise ImportError("Unknown magic number %s in %s" %
                                (ord(magic[0])+256*ord(magic[1]), filename))
            else:
                raise ImportError("Bad magic number: '%s'" % magic)

        if magic_int in (3361,):
            raise ImportError("%s is interim Python %s (%d) bytecode which is "
                              "not supported.\nFinal released versions are "
                              "supported." % (
                                  filename, magics.versions[magic],
                                  magics.magic2int(magic)))
        elif magic_int == 62135:
            fp.seek(0)
            return fix_dropbox_pyc(fp)
        elif magic_int == 62215:
            raise ImportError("%s is a dropbox-hacked Python %s (bytecode %d).\n"
                              "See https://github.com/kholia/dedrop for how to "
                              "decrypt." % (
                                  filename, version, magics.magic2int(magic)))

        try:
            # print version
            ts = fp.read(4)
            timestamp = unpack("I", ts)[0]
            my_magic_int = magics.magic2int(imp.get_magic())
            magic_int = magics.magic2int(magic)

            # Note: a higher magic number doesn't necessarily mean a later
            # release.  At Python 3.0 the magic number decreased
            # significantly. Hence the range below. Also note inclusion of
            # the size info, occurred within a Python major/minor
            # release. Hence the test on the magic value rather than
            # PYTHON_VERSION, although PYTHON_VERSION would probably work.
            if 3200 <= magic_int < 20121:
                source_size = unpack("I", fp.read(4))[0] # size mod 2**32
            else:
                source_size = None

            if get_code:
                if my_magic_int == magic_int:
                    bytecode = fp.read()
                    co = marshal.loads(bytecode)
                elif fast_load:
                    co = xdis.marsh.load(fp, magic_int, code_objects)
                else:
                    co = xdis.unmarshal.load_code(fp, magic_int, code_objects)
                pass
            else:
                co = None
        except:
            import traceback
            traceback.print_exc()
            raise ImportError("Ill-formed bytecode file %s" % filename)

    finally:
      fp.close()

    return version, timestamp, magic_int, co, is_pypy(magic_int), source_size
Beispiel #3
0
def load_module_from_file_object(fp,
                                 filename='<unknown>',
                                 code_objects=None,
                                 fast_load=False,
                                 get_code=True):
    """load a module from a file object without importing it.

    See :func:load_module for a list of return values.
    """

    if code_objects is None:
        code_objects = {}

    timestamp = 0
    try:
        magic = fp.read(4)
        magic_int = magics.magic2int(magic)

        # For reasons I don't understand, PyPy 3.2 stores a magic
        # of '0'...  The two values below are for Python 2.x and 3.x respectively
        if magic[0:1] in ['0', b'0']:
            magic = magics.int2magic(3180 + 7)

        try:
            # FIXME: use the internal routine below
            float_version = float(magics.versions[magic][:3])
            # float_version = magics.magic_int2float(magic_int)
        except KeyError:
            if magic_int in (2657, 22138):
                raise ImportError(
                    "This smells like Pyston which is not supported.")

            if len(magic) >= 2:
                raise ImportError(
                    "Unknown magic number %s in %s" %
                    (ord(magic[0:1]) + 256 * ord(magic[1:2]), filename))
            else:
                raise ImportError("Bad magic number: '%s'" % magic)

        if magic_int in (3010, 3020, 3030, 3040, 3050, 3060, 3061, 3361, 3371):
            raise ImportError(
                "%s is interim Python %s (%d) bytecode which is "
                "not supported.\nFinal released versions are "
                "supported." %
                (filename, magics.versions[magic], magics.magic2int(magic)))
        elif magic_int == 62135:
            fp.seek(0)
            return fix_dropbox_pyc(fp)
        elif magic_int == 62215:
            raise ImportError(
                "%s is a dropbox-hacked Python %s (bytecode %d).\n"
                "See https://github.com/kholia/dedrop for how to "
                "decrypt." %
                (filename, magics.versions[magic], magics.magic2int(magic)))

        try:
            # print version
            ts = fp.read(4)
            my_magic_int = magics.magic2int(imp.get_magic())
            magic_int = magics.magic2int(magic)

            if magic_int == 3393:
                timestamp = 0
                _ = unpack("<I", ts)[0]  # hash word 1
                _ = unpack("<I", fp.read(4))[0]  # hash word 2
            elif magic_int in (3394, 3401):
                timestamp = 0
                _ = unpack("<I", fp.read(4))[0]  # pep552_bits
            else:
                timestamp = unpack("<I", ts)[0]

            # Note: a higher magic number doesn't necessarily mean a later
            # release.  At Python 3.0 the magic number decreased
            # significantly. Hence the range below. Also note inclusion of
            # the size info, occurred within a Python major/minor
            # release. Hence the test on the magic value rather than
            # PYTHON_VERSION, although PYTHON_VERSION would probably work.
            if (((3200 <= magic_int < 20121) and
                 (magic_int not in (5892, 11913, 39170, 39171)))
                    or (magic_int in magics.IS_PYPY3)):

                source_size = unpack("<I", fp.read(4))[0]  # size mod 2**32
            else:
                source_size = None

            if get_code:
                if my_magic_int == magic_int:
                    bytecode = fp.read()
                    co = marshal.loads(bytecode)
                elif fast_load:
                    co = xdis.marsh.load(fp,
                                         magics.magicint2version[magic_int])
                else:
                    co = xdis.unmarshal.load_code(fp, magic_int, code_objects)
                pass
            else:
                co = None
        except:
            kind, msg = sys.exc_info()[0:2]
            import traceback
            traceback.print_exc()
            raise ImportError("Ill-formed bytecode file %s\n%s; %s" %
                              (filename, kind, msg))

    finally:
        fp.close()

    return float_version, timestamp, magic_int, co, is_pypy(
        magic_int), source_size
Beispiel #4
0
def load_module_from_file_object(fp, filename='<unknown>', code_objects=None, fast_load=False,
                get_code=True):
    """load a module from a file object without importing it.

    See :func:load_module for a list of return values.
    """

    if code_objects is None:
        code_objects = {}

    timestamp = 0
    try:
        magic = fp.read(4)
        magic_int = magics.magic2int(magic)

        # For reasons I don't understand, PyPy 3.2 stores a magic
        # of '0'...  The two values below are for Python 2.x and 3.x respectively
        if magic[0:1] in ['0', b'0']:
            magic = magics.int2magic(3180+7)

        try:
            # FIXME: use the internal routine below
            float_version = float(magics.versions[magic][:3])
            # float_version = magics.magic_int2float(magic_int)
        except KeyError:
            if magic_int in (2657, 22138):
                raise ImportError("This smells like Pyston which is not supported.")

            if len(magic) >= 2:
                raise ImportError("Unknown magic number %s in %s" %
                                (ord(magic[0:1])+256*ord(magic[1:2]), filename))
            else:
                raise ImportError("Bad magic number: '%s'" % magic)

        if magic_int in (3010, 3020, 3030, 3040, 3050, 3060, 3061, 3361, 3371):
            raise ImportError("%s is interim Python %s (%d) bytecode which is "
                              "not supported.\nFinal released versions are "
                              "supported." % (
                                  filename, magics.versions[magic],
                                  magics.magic2int(magic)))
        elif magic_int == 62135:
            fp.seek(0)
            return fix_dropbox_pyc(fp)
        elif magic_int == 62215:
            raise ImportError("%s is a dropbox-hacked Python %s (bytecode %d).\n"
                              "See https://github.com/kholia/dedrop for how to "
                              "decrypt." % (
                                  filename, magics.versions[magic],
                                  magics.magic2int(magic)))

        try:
            # print version
            ts = fp.read(4)
            my_magic_int = magics.magic2int(imp.get_magic())
            magic_int = magics.magic2int(magic)

            if magic_int == 3393:
                timestamp = 0
                _ = unpack("<I", ts)[0]         # hash word 1
                _ = unpack("<I", fp.read(4))[0] # hash word 2
            elif magic_int in (3394, 3401):
                timestamp = 0
                _ = unpack("<I", fp.read(4))[0] # pep552_bits
            else:
                timestamp = unpack("<I", ts)[0]

            # Note: a higher magic number doesn't necessarily mean a later
            # release.  At Python 3.0 the magic number decreased
            # significantly. Hence the range below. Also note inclusion of
            # the size info, occurred within a Python major/minor
            # release. Hence the test on the magic value rather than
            # PYTHON_VERSION, although PYTHON_VERSION would probably work.
            if 3200 <= magic_int < 20121 and magic_int not in (5892, 11913, 39170, 39171):
                source_size = unpack("<I", fp.read(4))[0] # size mod 2**32
            else:
                source_size = None

            if get_code:
                if my_magic_int == magic_int:
                    bytecode = fp.read()
                    co = marshal.loads(bytecode)
                elif fast_load:
                    co = xdis.marsh.load(fp, magics.magicint2version[magic_int])
                else:
                    co = xdis.unmarshal.load_code(fp, magic_int, code_objects)
                pass
            else:
                co = None
        except:
            kind, msg = sys.exc_info()[0:2]
            import traceback
            traceback.print_exc()
            raise ImportError("Ill-formed bytecode file %s\n%s; %s"
                              % (filename, kind, msg))

    finally:
      fp.close()

    return float_version, timestamp, magic_int, co, is_pypy(magic_int), source_size