Skip to content

Commit

Permalink
feat(helperFunctions): Introduce magic
Browse files Browse the repository at this point in the history
  • Loading branch information
maringuu committed Sep 12, 2024
1 parent 81eb5d3 commit fd453db
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/helperFunctions/magic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""This is a wrapper around pymagic.
It aims to provide the same API but with the ability to load multiple magic
files in the default api.
"""
from __future__ import annotations

import os
from os import PathLike

import magic as pymagic

from helperFunctions.fileSystem import get_src_dir

# On ubuntu this is provided by the libmagic-mgc package
_default_magic = os.getenv('MAGIC', '/usr/lib/file/magic.mgc')
_fact_magic = f'{get_src_dir()}/bin/firmware.mgc'
_internal_symlink_magic = f'{get_src_dir()}/bin/internal_symlink_magic.mgc'
_magic_file = f'{_internal_symlink_magic}:{_fact_magic}:{_default_magic}'

_instances = {}


def _get_magic_instance(**kwargs):
"""Returns an instance of pymagic.Maigc"""
# Dicts are not hashable but sorting and creating a tuple is a valid hash
key = hash(tuple(sorted(kwargs.items())))
instance = _instances.get(key)
if instance is None:
instance = _instances[key] = pymagic.Magic(**kwargs)
return instance


def from_file(filename: bytes | str | PathLike, magic_file: str | None = _magic_file, **kwargs) -> str:
"""Like pymagic's ``magic.from_file`` but it accepts all keyword arguments
that ``magic.Magic`` accepts.
"""
m = _get_magic_instance(magic_file=magic_file, **kwargs)
return m.from_file(filename)


def from_buffer(buf: bytes | str, magic_file: str | None = _magic_file, **kwargs) -> str:
"""Like pymagic's ``magic.from_buffer`` but it accepts all keyword arguments
that ``magic.Magic`` accepts.
"""
instance = _get_magic_instance(magic_file=magic_file, **kwargs)
return instance.from_buffer(buf)
7 changes: 7 additions & 0 deletions src/install/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ def main(distribution):

BIN_DIR.mkdir(exist_ok=True)

run_cmd_with_logging(
f'wget -O {BIN_DIR / "firmware"} https://github.com/fkie-cad/firmware-magic-database/releases/download/v0.2.0/firmware'
)
run_cmd_with_logging(f'file -C -m {BIN_DIR / "firmware"}')
run_cmd_with_logging(f'file -C -m {INSTALL_DIR / "internal_symlink_magic"}')
run_cmd_with_logging(f'mv {INSTALL_DIR / "internal_symlink_magic.mgc"} {BIN_DIR}')

apt_packages_path = INSTALL_DIR / 'apt-pkgs-common.txt'
dnf_packages_path = INSTALL_DIR / 'dnf-pkgs-common.txt'

Expand Down
6 changes: 6 additions & 0 deletions src/install/internal_symlink_magic
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# ====================== fact internal ======================

# ---- fact internal link representation ----
0 string symbolic\ link\ -> symbolic link
>17 string x to '%s'
!:mime inode/symlink
13 changes: 13 additions & 0 deletions src/test/unit/helperFunctions/test_magic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from helperFunctions import magic


def test_internal_magic():
assert magic.from_buffer('symbolic link -> /foo/bar', mime=True) == 'inode/symlink'


def test_firmware_magic():
assert magic.from_buffer('BOOTLOADER!', mime=False) == 'Mediatek bootloader'


def test_magic_from_file():
assert magic.from_file('/dev/null', mime=True) == 'inode/chardevice'

0 comments on commit fd453db

Please sign in to comment.