Skip to content

Commit d89c576

Browse files
authored
fix: zipfile.ZipInfo monkey-patch NameError after init cleanup (#79)
The _safe_zi wrapper referenced _orig_zi as a module-level global, but `del _orig_zi` at the end of the init block destroyed it before any call to ZipInfo() could use it. This broke all libraries that use zip-based formats (python-docx, openpyxl, etc.) with: NameError: name '_orig_zi' is not defined Wrap the patch in a function so _orig becomes a proper closure cell that survives the namespace cleanup. Adds a regression test using python-docx's Document() constructor. Signed-off-by: danbugs <danilochiarlone@gmail.com>
1 parent 581b8d8 commit d89c576

2 files changed

Lines changed: 24 additions & 7 deletions

File tree

examples/python-agent-driver/hl_pydriver.c

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -265,13 +265,15 @@ static void py_initialize_once(void)
265265
* writer (XLSX is a ZIP container). */
266266
PyRun_SimpleString(
267267
"import zipfile as _zf\n"
268-
"_orig_zi = _zf.ZipInfo.__init__\n"
269-
"def _safe_zi(self, filename='NoName', date_time=(1980,1,1,0,0,0)):\n"
270-
" if date_time[0] < 1980:\n"
271-
" date_time = (1980,1,1,0,0,0)\n"
272-
" _orig_zi(self, filename, date_time)\n"
273-
"_zf.ZipInfo.__init__ = _safe_zi\n"
274-
"del _zf, _orig_zi, _safe_zi\n");
268+
"def _patch_zipinfo():\n"
269+
" _orig = _zf.ZipInfo.__init__\n"
270+
" def _safe(self, filename='NoName', date_time=(1980,1,1,0,0,0)):\n"
271+
" if date_time[0] < 1980:\n"
272+
" date_time = (1980,1,1,0,0,0)\n"
273+
" _orig(self, filename, date_time)\n"
274+
" _zf.ZipInfo.__init__ = _safe\n"
275+
"_patch_zipinfo()\n"
276+
"del _patch_zipinfo, _zf\n");
275277

276278
/* Monkey-patch time.sleep to call the host via /dev/hcall.
277279
* Unikraft's cooperative scheduler on Hyperlight has no timer

host/tests/pyhl_runtime.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,21 @@ fn runtime_pandas_import() {
117117
assert_eq!(timing.exit_code, 0);
118118
}
119119

120+
// ---------------------------------------------------------------------------
121+
// zipfile.ZipInfo monkey-patch (pre-1980 date clamping)
122+
// ---------------------------------------------------------------------------
123+
124+
#[test]
125+
fn runtime_zipinfo_patch_survives_cleanup() {
126+
let Some((_home, mut rt)) = setup() else {
127+
return;
128+
};
129+
let timing = rt
130+
.run_code("from docx import Document\ndoc = Document()\nprint('ok')")
131+
.unwrap();
132+
assert_eq!(timing.exit_code, 0);
133+
}
134+
120135
// ---------------------------------------------------------------------------
121136
// Exit code propagation
122137
// ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)