# Path: mobsf/StaticAnalyzer/views/common/shared_func.py
# def unzip(app_path, ext_path):
#     logger.info('Unzipping')
#     try:
#         files = []
#         with zipfile.ZipFile(app_path, 'r') as zipptr:
#             for fileinfo in zipptr.infolist():
#                 filename = fileinfo.filename
#                 if not isinstance(filename, str):
#                     filename = str(
#                         filename, encoding='utf-8', errors='replace')
#                 files.append(filename)
#                 zipptr.extract(filename, ext_path)
#         return files
#     except Exception:
#         logger.exception('Unzipping Error')
#         if platform.system() == 'Windows':
#             logger.info('Not yet Implemented.')
#         else:
#             logger.info('Using the Default OS Unzip Utility.')
#             try:
#                 unzip_b = shutil.which('unzip')
#                 subprocess.call(
#                     [unzip_b, '-o', '-q', app_path, '-d', ext_path])
#                 dat = subprocess.check_output([unzip_b, '-qq', '-l', app_path])
#                 dat = dat.decode('utf-8').split('\n')
#                 files_det = ['Length   Date   Time   Name']
#                 files_det = files_det + dat
#                 return files_det
#             except Exception:
#                 logger.exception('Unzipping Error')
# 
# Path: mobsf/MobSF/utils.py
# def is_safe_path(safe_root, check_path):
#     """Detect Path Traversal."""
#     safe_root = os.path.realpath(os.path.normpath(safe_root))
#     check_path = os.path.realpath(os.path.normpath(check_path))
#     return os.path.commonprefix([check_path, safe_root]) == safe_root


import logging
from json import load
from shutil import move
from mobsf.StaticAnalyzer.views.common.shared_func import unzip
from mobsf.MobSF.utils import is_safe_path
    if 'manifest.json' not in files:
        logger.error('Manifest file not found in XAPK')
        return False
    manifest = app_dic['app_dir'] / 'manifest.json'
    with open(manifest, encoding='utf8', errors='ignore') as f:
        data = load(f)
    if not data:
        logger.error('Manifest file is empty')
        return False
    apks = data.get('split_apks')
    if not apks:
        logger.error('Split APKs not found')
        return False
    for a in apks:
        if a['id'] == 'base':
            base_apk = app_dic['app_dir'] / a['file']
            if is_safe_path(app_dic['app_dir'], base_apk):
                move(base_apk, apk)
                return True
    return None


def handle_split_apk(app_dic):
    """Unzip and Extract Split APKs."""
    checksum = app_dic['md5']
    apks = app_dic['app_dir'] / f'{checksum}.apk'
    # Check if previously extracted
    manifest = app_dic['app_dir'] / 'AndroidManifest.xml'
    if manifest.exists():
        return True

# Path: mobsf/StaticAnalyzer/views/common/shared_func.py
# def unzip(app_path, ext_path):
#     logger.info('Unzipping')
#     try:
#         files = []
#         with zipfile.ZipFile(app_path, 'r') as zipptr:
#             for fileinfo in zipptr.infolist():
#                 filename = fileinfo.filename
#                 if not isinstance(filename, str):
#                     filename = str(
#                         filename, encoding='utf-8', errors='replace')
#                 files.append(filename)
#                 zipptr.extract(filename, ext_path)
#         return files
#     except Exception:
#         logger.exception('Unzipping Error')
#         if platform.system() == 'Windows':
#             logger.info('Not yet Implemented.')
#         else:
#             logger.info('Using the Default OS Unzip Utility.')
#             try:
#                 unzip_b = shutil.which('unzip')
#                 subprocess.call(
#                     [unzip_b, '-o', '-q', app_path, '-d', ext_path])
#                 dat = subprocess.check_output([unzip_b, '-qq', '-l', app_path])
#                 dat = dat.decode('utf-8').split('\n')
#                 files_det = ['Length   Date   Time   Name']
#                 files_det = files_det + dat
#                 return files_det
#             except Exception:
#                 logger.exception('Unzipping Error')
# 
# Path: mobsf/MobSF/utils.py
# def is_safe_path(safe_root, check_path):
#     """Detect Path Traversal."""
#     safe_root = os.path.realpath(os.path.normpath(safe_root))
#     check_path = os.path.realpath(os.path.normpath(check_path))
#     return os.path.commonprefix([check_path, safe_root]) == safe_root


# Path: mobsf/StaticAnalyzer/views/android/xapk.py
import logging
from json import load
from shutil import move
from mobsf.StaticAnalyzer.views.common.shared_func import unzip
from mobsf.MobSF.utils import is_safe_path

    if 'manifest.json' not in files:
        logger.error('Manifest file not found in XAPK')
        return False
    manifest = app_dic['app_dir'] / 'manifest.json'
    with open(manifest, encoding='utf8', errors='ignore') as f:
        data = load(f)
    if not data:
        logger.error('Manifest file is empty')
        return False
    apks = data.get('split_apks')
    if not apks:
        logger.error('Split APKs not found')
        return False
    for a in apks:
        if a['id'] == 'base':
            base_apk = app_dic['app_dir'] / a['file']
            if is_safe_path(app_dic['app_dir'], base_apk):
                move(base_apk, apk)
                return True
    return None


def handle_split_apk(app_dic):
    """Unzip and Extract Split APKs."""
    checksum = app_dic['md5']
    apks = app_dic['app_dir'] / f'{checksum}.apk'
    # Check if previously extracted
    manifest = app_dic['app_dir'] / 'AndroidManifest.xml'
    if manifest.exists():
        return True

    files = unzip(apks.as_posix(), app_dic['app_dir'])