Example #1
0
    def get_code(self, fullname: str) -> Any:
        """
        Decrypt, and interpret as Python bytecode into a module return.

        Args:
            fullname: The name of the module to decrypt and compile

        Returns:
            Compiled bytecode
        """
        path = self.get_filename(fullname)
        data = self.get_data(path)

        # Relative paths are impossible on Windows if the target file is on a different drive letter to the working directory
        try:
            r_path = relpath(path)
        except:
            # well, we tried
            r_path = path
        # It is important to normalize path case for platforms like Windows
        data = decrypt(data, PYCEPathFinder.KEYS[normcase(r_path)])

        # Call _classify_pyc to do basic validation of the pyc but ignore the
        # result. There's no source to check against.
        exc_details = {
            'name': fullname,
            'path': path,
        }
        _classify_pyc(data, fullname, exc_details)

        return _compile_bytecode(
            memoryview(data)[16:],
            name=fullname,
            bytecode_path=path,
        )
Example #2
0
    def get_code(self, fullname: str) -> Any:
        """
        Decrypt, and interpret as Python bytecode into a module return.

        Args:
            fullname: The name of the module to decrypt and compile

        Returns:
            Compiled bytecode
        """
        path = self.get_filename(fullname)
        data = self.get_data(path)

        # It is important to normalize path case for platforms like Windows
        data = decrypt(data, PYCEPathFinder.KEYS[normcase(relpath(path))])

        # Call _classify_pyc to do basic validation of the pyc but ignore the
        # result. There's no source to check against.
        exc_details = {
            'name': fullname,
            'path': path,
        }
        _classify_pyc(data, fullname, exc_details)

        return _compile_bytecode(
            memoryview(data)[16:],
            name=fullname,
            bytecode_path=path,
        )
Example #3
0
    def get_code(self, fullname):
        """Concrete implementation of InspectLoader.get_code.

        Reading of bytecode requires path_stats to be implemented. To write
        bytecode, set_data must also be implemented.

        """
        source_path = self.get_filename(fullname)
        source_mtime = None
        try:
            # XXX: begin our change
            bytecode_path = da_cache_from_source(source_path)
            # XXX: end our change
        except NotImplementedError:
            bytecode_path = None
        else:
            # XXX: begin our change
            if not get_runtime_option('recompile', default=False):
                # XXX: end our change
                try:
                    st = self.path_stats(source_path)
                except IOError:
                    pass
                else:
                    source_mtime = int(st['mtime'])
                    try:
                        data = self.get_data(bytecode_path)
                    except OSError:
                        pass
                    else:
                        try:
                            bytes_data = _validate_bytecode_header(
                                data,
                                source_stats=st,
                                name=fullname,
                                path=bytecode_path)
                        except (ImportError, EOFError):
                            pass
                        else:
                            _verbose_message('{} matches {}', bytecode_path,
                                             source_path)
                            return _compile_bytecode(
                                bytes_data,
                                name=fullname,
                                bytecode_path=bytecode_path,
                                source_path=source_path)
        source_bytes = self.get_data(source_path)
        code_object = self.source_to_code(source_bytes, source_path)
        _verbose_message('code object from {}', source_path)
        if (not sys.dont_write_bytecode and bytecode_path is not None
                and source_mtime is not None):
            data = _code_to_bytecode(code_object, source_mtime,
                                     len(source_bytes))
            try:
                self._cache_bytecode(source_path, bytecode_path, data)
                _verbose_message('wrote {!r}', bytecode_path)
            except NotImplementedError:
                pass
        return code_object
Example #4
0
    def get_code(self, fullname):
        """Concrete implementation of InspectLoader.get_code.

        Reading of bytecode requires path_stats to be implemented. To write
        bytecode, set_data must also be implemented.

        """
        source_path = self.get_filename(fullname)
        source_mtime = None
        try:
            # XXX: begin our change
            bytecode_path = da_cache_from_source(source_path)
            # XXX: end our change
        except NotImplementedError:
            bytecode_path = None
        else:
            # XXX: begin our change
            if not common.get_runtime_option('recompile', default=False):
                # XXX: end our change
                try:
                    st = self.path_stats(source_path)
                except IOError:
                    pass
                else:
                    source_mtime = int(st['mtime'])
                    try:
                        data = self.get_data(bytecode_path)
                    except OSError:
                        pass
                    else:
                        try:
                            bytes_data = _validate_bytecode_header(data,
                                    source_stats=st, name=fullname,
                                    path=bytecode_path)
                        except (ImportError, EOFError):
                            pass
                        else:
                            _verbose_message('{} matches {}', bytecode_path,
                                             source_path)
                            return _compile_bytecode(bytes_data, name=fullname,
                                                     bytecode_path=bytecode_path,
                                                     source_path=source_path)
        source_bytes = self.get_data(source_path)
        code_object = self.source_to_code(source_bytes, source_path)
        _verbose_message('code object from {}', source_path)
        if (not sys.dont_write_bytecode and bytecode_path is not None and
                source_mtime is not None):
            data = _code_to_bytecode(code_object, source_mtime,
                    len(source_bytes))
            try:
                self._cache_bytecode(source_path, bytecode_path, data)
                _verbose_message('wrote {!r}', bytecode_path)
            except NotImplementedError:
                pass
        return code_object
Example #5
0
    def get_code(self, fullname: str) -> Any:
        """
        Decrypt, and interpret as Python bytecode into a module return.

        Args:
            fullname: The name of the module to decrypt and compile

        Returns:
            Compiled bytecode
        """
        path = self.get_filename(fullname)
        data = self.get_data(path)

        # print("XPYCE FileLoader Fullname: {}, path from get_filename is {}".format(fullname, path))
        # It is important to normalize path case for platforms like Windows
        decryption_key = None
        for prefix in PREFIXES:
            if decryption_key:
                break
            lookup_module = relpath(path, start=prefix).replace('/',
                                                                '.').replace(
                                                                    '\\', '.')
            for module in XPYCEPathFinder.KEYS:
                if module == lookup_module:
                    decryption_key = XPYCEPathFinder.KEYS[module]
                    break
        if not decryption_key:
            raise KeyError(
                "Cannot find decryption_key for module '{}'".format(fullname))

        try:
            data = decrypt(data, decryption_key)
        except Exception as e:
            print("Could not decrypt module '{}' with provided decryption_key".
                  format(fullname))
            raise e

        # .pyc changed from 3 32-bit words to 4 32-bit words with Python3.7
        # Skip over the header to get to the raw data

        if sys.version_info.minor < 7:
            bytes_data = data[12:]
        else:
            bytes_data = data[16:]

        return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path)
Example #6
0
    def get_code(self, fullname: str) -> Any:
        """
        Decrypt, and interpret as Python bytecode into a module return.

        Args:
            fullname: The name of the module to decrypt and compile

        Returns:
            Compiled bytecode
        """
        path = self.get_filename(fullname)
        data = self.get_data(path)

        # It is important to normalize path case for platforms like Windows
        data = decrypt(data, PYCEPathFinder.KEYS[normcase(relpath(path))])

        bytes_data = _validate_bytecode_header(data, name=fullname, path=path)

        return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path)
Example #7
0
    def get_code(self, fullname):
        """Concrete implementation of InspectLoader.get_code.

        Reading of bytecode requires path_stats to be implemented. To write
        bytecode, set_data must also be implemented.

        """
        source_path = self.get_filename(fullname)
        source_mtime = None
        source_bytes = None
        source_hash = None
        hash_based = False
        check_source = True
        try:
            # XXX: begin our change
            bytecode_path = da_cache_from_source(source_path)
            # XXX: end our change
        except NotImplementedError:
            bytecode_path = None
        else:
            # XXX: begin our change
            if not common.get_runtime_option('recompile', default=False):
                # XXX: end our change
                try:
                    st = self.path_stats(source_path)
                except OSError:
                    pass
                else:
                    source_mtime = int(st['mtime'])
                    try:
                        data = self.get_data(bytecode_path)
                    except OSError:
                        pass
                    else:
                        exc_details = {
                            'name': fullname,
                            'path': bytecode_path,
                        }
                        try:
                            flags = _classify_pyc(data, fullname, exc_details)
                            bytes_data = memoryview(data)[16:]
                            hash_based = flags & 0b1 != 0
                            if hash_based:
                                check_source = flags & 0b10 != 0
                                if (_imp.check_hash_based_pycs != 'never' and
                                    (check_source or
                                     _imp.check_hash_based_pycs == 'always')):
                                    source_bytes = self.get_data(source_path)
                                    source_hash = _imp.source_hash(
                                        _RAW_MAGIC_NUMBER,
                                        source_bytes,
                                    )
                                    _validate_hash_pyc(data, source_hash, fullname,
                                                       exc_details)
                            else:
                                _validate_timestamp_pyc(
                                    data,
                                    source_mtime,
                                    st['size'],
                                    fullname,
                                    exc_details,
                                )
                        except (ImportError, EOFError):
                            pass
                        else:
                            _verbose_message('{} matches {}', bytecode_path,
                                                        source_path)
                            return _compile_bytecode(bytes_data, name=fullname,
                                                     bytecode_path=bytecode_path,
                                                     source_path=source_path)
        if source_bytes is None:
            source_bytes = self.get_data(source_path)
        code_object = self.source_to_code(source_bytes, source_path)
        _verbose_message('code object from {}', source_path)
        if (not sys.dont_write_bytecode and bytecode_path is not None and
                source_mtime is not None):
            if hash_based:
                if source_hash is None:
                    source_hash = _imp.source_hash(source_bytes)
                data = _code_to_hash_pyc(code_object, source_hash, check_source)
            else:
                data = _code_to_timestamp_pyc(code_object, source_mtime,
                                              len(source_bytes))
            try:
                self._cache_bytecode(source_path, bytecode_path, data)
                _verbose_message('wrote {!r}', bytecode_path)
            except NotImplementedError:
                pass
        return code_object
Example #8
0
 def get_code(self, fullname):
     path = self.get_filename(fullname)
     data = self.get_data(path)
     bytes_data = memoryview(data)[16:]
     # bytes_data = _validate_bytecode_header(data, name=fullname, path=path)
     return _compile_bytecode(bytes_data, name=fullname, bytecode_path=path)
Example #9
0
    def get_code(self, fullname):
        """Concrete implementation of InspectLoader.get_code.

        Reading of bytecode requires path_stats to be implemented. To write
        bytecode, set_data must also be implemented.

        """
        source_path = self.get_filename(fullname)
        source_mtime = None
        source_bytes = None
        source_hash = None
        hash_based = False
        check_source = True
        try:
            # XXX: begin our change
            bytecode_path = da_cache_from_source(source_path)
            # XXX: end our change
        except NotImplementedError:
            bytecode_path = None
        else:
            # XXX: begin our change
            if not common.get_runtime_option('recompile', default=False):
                # XXX: end our change
                try:
                    st = self.path_stats(source_path)
                except OSError:
                    pass
                else:
                    source_mtime = int(st['mtime'])
                    try:
                        data = self.get_data(bytecode_path)
                    except OSError:
                        pass
                    else:
                        exc_details = {
                            'name': fullname,
                            'path': bytecode_path,
                        }
                        try:
                            flags = _classify_pyc(data, fullname, exc_details)
                            bytes_data = memoryview(data)[16:]
                            hash_based = flags & 0b1 != 0
                            if hash_based:
                                check_source = flags & 0b10 != 0
                                if (_imp.check_hash_based_pycs != 'never' and
                                    (check_source or _imp.check_hash_based_pycs
                                     == 'always')):
                                    source_bytes = self.get_data(source_path)
                                    source_hash = _imp.source_hash(
                                        _RAW_MAGIC_NUMBER,
                                        source_bytes,
                                    )
                                    _validate_hash_pyc(data, source_hash,
                                                       fullname, exc_details)
                            else:
                                _validate_timestamp_pyc(
                                    data,
                                    source_mtime,
                                    st['size'],
                                    fullname,
                                    exc_details,
                                )
                        except (ImportError, EOFError):
                            pass
                        else:
                            _verbose_message('{} matches {}', bytecode_path,
                                             source_path)
                            return _compile_bytecode(
                                bytes_data,
                                name=fullname,
                                bytecode_path=bytecode_path,
                                source_path=source_path)
        if source_bytes is None:
            source_bytes = self.get_data(source_path)
        code_object = self.source_to_code(source_bytes, source_path)
        _verbose_message('code object from {}', source_path)
        if (not sys.dont_write_bytecode and bytecode_path is not None
                and source_mtime is not None):
            if hash_based:
                if source_hash is None:
                    source_hash = _imp.source_hash(source_bytes)
                data = _code_to_hash_pyc(code_object, source_hash,
                                         check_source)
            else:
                data = _code_to_timestamp_pyc(code_object, source_mtime,
                                              len(source_bytes))
            try:
                self._cache_bytecode(source_path, bytecode_path, data)
                _verbose_message('wrote {!r}', bytecode_path)
            except NotImplementedError:
                pass
        return code_object