Skip to content

Commit f95576d

Browse files
committed
fix: zipfile.ZipInfo monkey-patch NameError after init cleanup
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 20ccc2d commit f95576d

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
@@ -264,13 +264,15 @@ static void py_initialize_once(void)
264264
* writer (XLSX is a ZIP container). */
265265
PyRun_SimpleString(
266266
"import zipfile as _zf\n"
267-
"_orig_zi = _zf.ZipInfo.__init__\n"
268-
"def _safe_zi(self, filename='NoName', date_time=(1980,1,1,0,0,0)):\n"
269-
" if date_time[0] < 1980:\n"
270-
" date_time = (1980,1,1,0,0,0)\n"
271-
" _orig_zi(self, filename, date_time)\n"
272-
"_zf.ZipInfo.__init__ = _safe_zi\n"
273-
"del _zf, _orig_zi, _safe_zi\n");
267+
"def _patch_zipinfo():\n"
268+
" _orig = _zf.ZipInfo.__init__\n"
269+
" def _safe(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(self, filename, date_time)\n"
273+
" _zf.ZipInfo.__init__ = _safe\n"
274+
"_patch_zipinfo()\n"
275+
"del _patch_zipinfo, _zf\n");
274276

275277
/* Monkey-patch time.sleep to call the host via /dev/hcall.
276278
* 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)