Skip to content

SetRulesDir crashes when Rules directory is read-only #99

@joanmarie

Description

@joanmarie

When Rules are installed to a read-only directory (e.g. /usr/share/), SetRulesDir panics because zip_extract_shim tries to extract the .zip files inside each language/braille subdirectory in-place.

Reproduced with the prebuilt libmathcat_py-64-3.13-linux binary and Rules.zip from the 0.7.5 release on Linux.

Steps to reproduce:

Save and run this python script:

import os
import shutil
import sys
import tempfile
import urllib.request
import zipfile

base_url = "https://github.com/daisy/MathCATForPython/releases/download/0.7.5"

# Fetch the prebuilt Linux binary and Rules
work_dir = tempfile.mkdtemp()
for name in ["libmathcat_py-64-3.13-linux.zip", "Rules.zip"]:
    dest = os.path.join(work_dir, name)
    print(f"Downloading {name}...")
    urllib.request.urlretrieve(f"{base_url}/{name}", dest)
    with zipfile.ZipFile(dest) as zf:
        zf.extractall(work_dir)

# Make Rules read-only (like /usr/share on Linux)
for root, dirs, _files in os.walk(os.path.join(work_dir, "Rules")):
    for d in dirs:
        os.chmod(os.path.join(root, d), 0o555)

# Import the .so from the work dir
sys.path.insert(0, work_dir)
import libmathcat_py

# This crashes with PermissionDenied
print("Calling SetRulesDir on read-only directory...")
libmathcat_py.SetRulesDir(os.path.join(work_dir, "Rules"))

When I run this locally, I get the following:

$ python mathcat-crash.py
Downloading libmathcat_py-64-3.13-linux.zip...
Downloading Rules.zip...
Calling SetRulesDir on read-only directory...

thread '<unnamed>' (3596307) panicked at /home/runner/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mathcat-0.7.5/src/shim_filesystem.rs:371:46:
Zip extraction failed: Io(Os { code: 13, kind: PermissionDenied, message: "Permission denied" })
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Traceback (most recent call last):
  File "/home/jd/mathcat-crash.py", line 30, in <module>
    libmathcat_py.SetRulesDir(os.path.join(work_dir, "Rules"))
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pyo3_runtime.PanicException: Zip extraction failed: Io(Os { code: 13, kind: PermissionDenied, message: "Permission denied" })

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions