just-bash 2.7.0 → 2.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/chunks/alias-MGDOL4KG.js +7 -0
- package/dist/bin/chunks/awk2-TV3KCXON.js +21 -0
- package/dist/bin/{shell/chunks/base64-O7TCK5TL.js → chunks/base64-43KPK6TL.js} +1 -1
- package/dist/bin/chunks/bash-OAUBNRSG.js +6 -0
- package/dist/bin/{shell/chunks/cat-AJXZOSPN.js → chunks/cat-HNXE2ES2.js} +1 -1
- package/dist/bin/chunks/chunk-4PRVMER6.js +2 -0
- package/dist/bin/chunks/chunk-GANRM5LO.js +17 -0
- package/dist/bin/chunks/chunk-GIFF636B.js +2 -0
- package/dist/bin/chunks/chunk-GZHFXDDO.js +10 -0
- package/dist/bin/chunks/chunk-JBABAK44.js +4 -0
- package/dist/bin/chunks/chunk-SE4C7FJY.js +33 -0
- package/dist/bin/chunks/chunk-VHH2M5JC.js +74 -0
- package/dist/bin/chunks/chunk-XI5LBYFX.js +6 -0
- package/dist/bin/chunks/{column-TSFEMTG6.js → column-HQ4AK5DM.js} +1 -1
- package/dist/bin/chunks/{cp-XXWRVG2D.js → cp-VFXCUKXO.js} +1 -1
- package/dist/bin/chunks/{curl-TH7YRBSA.js → curl-7IUASLUJ.js} +1 -1
- package/dist/bin/chunks/{diff-GI3QVUGD.js → diff-ZGXLP3DN.js} +1 -1
- package/dist/bin/chunks/{du-XQPYLN3H.js → du-PECPOFQT.js} +1 -1
- package/dist/bin/chunks/env-W6IMQ43Y.js +9 -0
- package/dist/bin/chunks/expansion-LVCGISX6.js +2 -0
- package/dist/bin/chunks/expr-433HIVAI.js +5 -0
- package/dist/bin/chunks/find-KHOYETRP.js +11 -0
- package/dist/bin/{shell/chunks/grep-VX7MJMVN.js → chunks/grep-X7UU5FD6.js} +1 -1
- package/dist/bin/chunks/{gzip-YXK3WZQL.js → gzip-5ILPB46W.js} +1 -1
- package/dist/bin/chunks/history-56DL6SXU.js +3 -0
- package/dist/bin/{shell/chunks/jq-RGZHJNXC.js → chunks/jq-QR3PX7FE.js} +1 -1
- package/dist/bin/{shell/chunks/ls-BEHQBUMC.js → chunks/ls-5LN47VHU.js} +1 -1
- package/dist/bin/{shell/chunks/mkdir-XJABRAUN.js → chunks/mkdir-XMSNS6S5.js} +1 -1
- package/dist/bin/chunks/{mv-3ATZ2ABL.js → mv-P4KHB27X.js} +1 -1
- package/dist/bin/chunks/{paste-FT6WBQZG.js → paste-UCH462KK.js} +1 -1
- package/dist/bin/chunks/{printf-YPXD4CRE.js → printf-XPBSFXJE.js} +1 -1
- package/dist/bin/chunks/{python3-JGT65AEB.js → python3-ZWX5SFJ3.js} +5 -5
- package/dist/bin/chunks/rg-RSJPHAP5.js +33 -0
- package/dist/bin/chunks/{rm-2PKAWTSQ.js → rm-S7ASVG34.js} +1 -1
- package/dist/bin/chunks/{rmdir-GOODLY5W.js → rmdir-OEMA5ZTD.js} +1 -1
- package/dist/bin/chunks/{sed-JPDTWF4W.js → sed-356P4DZB.js} +25 -25
- package/dist/bin/chunks/{stat-UEQ7KMY5.js → stat-ZZVPXHLF.js} +1 -1
- package/dist/bin/chunks/{tar-LFENC54A.js → tar-CLEBMI4R.js} +18 -18
- package/dist/bin/{shell/chunks/tee-ZFIT2GTM.js → chunks/tee-XSKPK43X.js} +1 -1
- package/dist/bin/chunks/time-F4NVQOJH.js +14 -0
- package/dist/bin/{shell/chunks/tr-MBLEXZBI.js → chunks/tr-FMT6JWLE.js} +1 -1
- package/dist/bin/chunks/{tree-DQBEJH47.js → tree-WC3AXFHC.js} +1 -1
- package/dist/bin/chunks/{uniq-IXHB2FVS.js → uniq-NNXAFO6D.js} +1 -1
- package/dist/bin/{shell/chunks/wc-SAOHEZYP.js → chunks/wc-CZ2TD6T6.js} +1 -1
- package/dist/bin/chunks/{which-FCDFBOMN.js → which-5QEJAXNR.js} +1 -1
- package/dist/bin/chunks/worker.js +382 -64
- package/dist/bin/chunks/xan-UZG3SZON.js +140 -0
- package/dist/bin/chunks/{xan-view-6Z6TWXMY.js → xan-view-5SZBYPLG.js} +1 -1
- package/dist/bin/chunks/{yq-PFV4T2PV.js → yq-T255J4ZP.js} +1 -1
- package/dist/bin/just-bash.js +251 -251
- package/dist/bin/shell/chunks/alias-MGDOL4KG.js +7 -0
- package/dist/bin/shell/chunks/awk2-TV3KCXON.js +21 -0
- package/dist/bin/{chunks/base64-O7TCK5TL.js → shell/chunks/base64-43KPK6TL.js} +1 -1
- package/dist/bin/shell/chunks/bash-OAUBNRSG.js +6 -0
- package/dist/bin/{chunks/cat-AJXZOSPN.js → shell/chunks/cat-HNXE2ES2.js} +1 -1
- package/dist/bin/shell/chunks/chunk-4PRVMER6.js +2 -0
- package/dist/bin/shell/chunks/chunk-GANRM5LO.js +17 -0
- package/dist/bin/shell/chunks/chunk-GIFF636B.js +2 -0
- package/dist/bin/shell/chunks/chunk-GZHFXDDO.js +10 -0
- package/dist/bin/shell/chunks/chunk-JBABAK44.js +4 -0
- package/dist/bin/shell/chunks/chunk-SE4C7FJY.js +33 -0
- package/dist/bin/shell/chunks/chunk-VHH2M5JC.js +74 -0
- package/dist/bin/shell/chunks/chunk-XI5LBYFX.js +6 -0
- package/dist/bin/shell/chunks/{column-TSFEMTG6.js → column-HQ4AK5DM.js} +1 -1
- package/dist/bin/shell/chunks/{cp-XXWRVG2D.js → cp-VFXCUKXO.js} +1 -1
- package/dist/bin/shell/chunks/{curl-TH7YRBSA.js → curl-7IUASLUJ.js} +1 -1
- package/dist/bin/shell/chunks/{diff-GI3QVUGD.js → diff-ZGXLP3DN.js} +1 -1
- package/dist/bin/shell/chunks/{du-XQPYLN3H.js → du-PECPOFQT.js} +1 -1
- package/dist/bin/shell/chunks/env-W6IMQ43Y.js +9 -0
- package/dist/bin/shell/chunks/expansion-LVCGISX6.js +2 -0
- package/dist/bin/shell/chunks/expr-433HIVAI.js +5 -0
- package/dist/bin/shell/chunks/find-KHOYETRP.js +11 -0
- package/dist/bin/{chunks/grep-VX7MJMVN.js → shell/chunks/grep-X7UU5FD6.js} +1 -1
- package/dist/bin/shell/chunks/{gzip-YXK3WZQL.js → gzip-5ILPB46W.js} +1 -1
- package/dist/bin/shell/chunks/history-56DL6SXU.js +3 -0
- package/dist/bin/{chunks/jq-RGZHJNXC.js → shell/chunks/jq-QR3PX7FE.js} +1 -1
- package/dist/bin/{chunks/ls-BEHQBUMC.js → shell/chunks/ls-5LN47VHU.js} +1 -1
- package/dist/bin/{chunks/mkdir-XJABRAUN.js → shell/chunks/mkdir-XMSNS6S5.js} +1 -1
- package/dist/bin/shell/chunks/{mv-3ATZ2ABL.js → mv-P4KHB27X.js} +1 -1
- package/dist/bin/shell/chunks/{paste-FT6WBQZG.js → paste-UCH462KK.js} +1 -1
- package/dist/bin/shell/chunks/{printf-YPXD4CRE.js → printf-XPBSFXJE.js} +1 -1
- package/dist/bin/shell/chunks/{python3-JGT65AEB.js → python3-ZWX5SFJ3.js} +5 -5
- package/dist/bin/shell/chunks/rg-RSJPHAP5.js +33 -0
- package/dist/bin/shell/chunks/{rm-2PKAWTSQ.js → rm-S7ASVG34.js} +1 -1
- package/dist/bin/shell/chunks/{rmdir-GOODLY5W.js → rmdir-OEMA5ZTD.js} +1 -1
- package/dist/bin/shell/chunks/{sed-JPDTWF4W.js → sed-356P4DZB.js} +25 -25
- package/dist/bin/shell/chunks/{stat-UEQ7KMY5.js → stat-ZZVPXHLF.js} +1 -1
- package/dist/bin/shell/chunks/{tar-LFENC54A.js → tar-CLEBMI4R.js} +18 -18
- package/dist/bin/{chunks/tee-ZFIT2GTM.js → shell/chunks/tee-XSKPK43X.js} +1 -1
- package/dist/bin/shell/chunks/time-F4NVQOJH.js +14 -0
- package/dist/bin/{chunks/tr-MBLEXZBI.js → shell/chunks/tr-FMT6JWLE.js} +1 -1
- package/dist/bin/shell/chunks/{tree-DQBEJH47.js → tree-WC3AXFHC.js} +1 -1
- package/dist/bin/shell/chunks/{uniq-IXHB2FVS.js → uniq-NNXAFO6D.js} +1 -1
- package/dist/bin/{chunks/wc-SAOHEZYP.js → shell/chunks/wc-CZ2TD6T6.js} +1 -1
- package/dist/bin/shell/chunks/{which-FCDFBOMN.js → which-5QEJAXNR.js} +1 -1
- package/dist/bin/shell/chunks/xan-UZG3SZON.js +140 -0
- package/dist/bin/shell/chunks/{xan-view-6Z6TWXMY.js → xan-view-5SZBYPLG.js} +1 -1
- package/dist/bin/shell/chunks/{yq-PFV4T2PV.js → yq-T255J4ZP.js} +1 -1
- package/dist/bin/shell/shell.js +226 -226
- package/dist/bundle/browser.js +892 -863
- package/dist/bundle/chunks/alias-YGOORMWI.js +6 -0
- package/dist/bundle/chunks/awk2-PTU7M2NS.js +20 -0
- package/dist/bundle/chunks/{base64-3BME25ON.js → base64-2JFR3HGT.js} +1 -1
- package/dist/bundle/chunks/bash-BYWM5OPC.js +5 -0
- package/dist/bundle/chunks/{cat-MV4K6AUA.js → cat-GPKR7D6K.js} +1 -1
- package/dist/bundle/chunks/chunk-F55TLFGB.js +9 -0
- package/dist/bundle/chunks/chunk-GMMICOEF.js +73 -0
- package/dist/bundle/chunks/chunk-HWKDQ44K.js +3 -0
- package/dist/bundle/chunks/chunk-IJXFPKNC.js +1 -0
- package/dist/bundle/chunks/chunk-OJDRYQWQ.js +1 -0
- package/dist/bundle/chunks/chunk-PHXIZ5A4.js +5 -0
- package/dist/bundle/chunks/chunk-TMKMSBKB.js +16 -0
- package/dist/bundle/chunks/chunk-YNYSPYQ5.js +32 -0
- package/dist/bundle/chunks/{column-XPDNNO5Y.js → column-R6OLMEUA.js} +1 -1
- package/dist/bundle/chunks/{cp-PBJT3GBF.js → cp-NJSENVKC.js} +1 -1
- package/dist/bundle/chunks/{curl-XLP4VABU.js → curl-QDCXHQMX.js} +1 -1
- package/dist/bundle/chunks/{diff-ZLJYSBRK.js → diff-ELUS3RW7.js} +1 -1
- package/dist/bundle/chunks/{du-NQXEC3EF.js → du-T4JUAAB2.js} +1 -1
- package/dist/bundle/chunks/env-M3AXY56V.js +8 -0
- package/dist/bundle/chunks/expansion-OP223NMV.js +1 -0
- package/dist/bundle/chunks/expr-YSFDPKPV.js +4 -0
- package/dist/bundle/chunks/find-WTVSUXL3.js +10 -0
- package/dist/bundle/chunks/{grep-NIC6JNLH.js → grep-F7ILPL2H.js} +1 -1
- package/dist/bundle/chunks/{gzip-L3NDJG3F.js → gzip-4P4KGYT5.js} +1 -1
- package/dist/bundle/chunks/history-TMBGOQO6.js +2 -0
- package/dist/bundle/chunks/{jq-RLRYRPOJ.js → jq-RIXCOULU.js} +1 -1
- package/dist/bundle/chunks/{ls-5W3NU5OJ.js → ls-PUJHEPXS.js} +1 -1
- package/dist/bundle/chunks/{mkdir-7UKY4B3B.js → mkdir-SF2UE4KB.js} +1 -1
- package/dist/bundle/chunks/{mv-FXHEKRTB.js → mv-JPBZPM4O.js} +1 -1
- package/dist/bundle/chunks/{paste-QTGVEPH5.js → paste-QAP6Y75J.js} +1 -1
- package/dist/bundle/chunks/{printf-66XGXFCD.js → printf-OAPYPRGV.js} +1 -1
- package/dist/bundle/chunks/{python3-3OP7EKER.js → python3-SKZGHYDO.js} +5 -5
- package/dist/bundle/chunks/rg-O3ZIRBAJ.js +32 -0
- package/dist/bundle/chunks/{rm-I2SRVF7H.js → rm-MJFRIDNT.js} +1 -1
- package/dist/bundle/chunks/{rmdir-XFQE4ZYV.js → rmdir-DU6C7ZEO.js} +1 -1
- package/dist/bundle/chunks/{sed-IV6HLDXU.js → sed-P5OTD3EL.js} +25 -25
- package/dist/bundle/chunks/{stat-IVQBBOKN.js → stat-IOLJTP7U.js} +1 -1
- package/dist/bundle/chunks/{tar-LWIHPMT6.js → tar-5V4PGBFL.js} +18 -18
- package/dist/bundle/chunks/{tee-2QU4NRSJ.js → tee-4KHTWVWB.js} +1 -1
- package/dist/bundle/chunks/time-EGF4KTWV.js +13 -0
- package/dist/bundle/chunks/{tr-EDGW5FG6.js → tr-P43NRVKL.js} +1 -1
- package/dist/bundle/chunks/{tree-MEM64BW3.js → tree-UFVZH4SS.js} +1 -1
- package/dist/bundle/chunks/{uniq-47QVBRNC.js → uniq-XBP4SJA3.js} +1 -1
- package/dist/bundle/chunks/{wc-HE5XARI4.js → wc-VDPK3LVS.js} +1 -1
- package/dist/bundle/chunks/{which-UBLRBDHN.js → which-GF77XMJD.js} +1 -1
- package/dist/bundle/chunks/worker.js +382 -64
- package/dist/bundle/chunks/xan-HKCQ46BH.js +139 -0
- package/dist/bundle/chunks/{xan-view-DMFUMZG7.js → xan-view-ECQUO7AJ.js} +1 -1
- package/dist/bundle/chunks/{yq-L665QPQU.js → yq-6SPP5BHS.js} +1 -1
- package/dist/bundle/index.js +253 -253
- package/dist/commands/awk/interpreter/context.d.ts +3 -2
- package/dist/commands/query-engine/evaluator.d.ts +2 -2
- package/dist/commands/query-engine/safe-object.d.ts +49 -0
- package/dist/commands/query-engine/value-operations.d.ts +1 -0
- package/dist/commands/search-engine/matcher.d.ts +2 -1
- package/dist/commands/search-engine/regex.d.ts +2 -1
- package/dist/commands/xan/aggregation.d.ts +1 -1
- package/dist/commands/xan/csv.d.ts +16 -0
- package/dist/interpreter/alias-expansion.d.ts +1 -1
- package/dist/interpreter/helpers/ifs.d.ts +4 -4
- package/dist/interpreter/simple-command-assignments.d.ts +1 -1
- package/dist/interpreter/types.d.ts +2 -2
- package/dist/types.d.ts +2 -2
- package/package.json +3 -2
- package/dist/bin/chunks/alias-EGIS5LUE.js +0 -7
- package/dist/bin/chunks/awk2-GFEJOWML.js +0 -21
- package/dist/bin/chunks/bash-PGDTHIM2.js +0 -6
- package/dist/bin/chunks/chunk-26Q3PZQ6.js +0 -2
- package/dist/bin/chunks/chunk-FSAGDARS.js +0 -74
- package/dist/bin/chunks/chunk-IRUD2E3M.js +0 -17
- package/dist/bin/chunks/chunk-KD3EODLB.js +0 -6
- package/dist/bin/chunks/chunk-TA7RUHGQ.js +0 -4
- package/dist/bin/chunks/chunk-UUQYHLBO.js +0 -10
- package/dist/bin/chunks/env-7A4MH7BJ.js +0 -9
- package/dist/bin/chunks/expansion-BOR3ELLC.js +0 -2
- package/dist/bin/chunks/expr-RMGXYNQJ.js +0 -5
- package/dist/bin/chunks/find-PHDZK64M.js +0 -11
- package/dist/bin/chunks/history-G5C2J2OY.js +0 -3
- package/dist/bin/chunks/rg-RSDLLECO.js +0 -33
- package/dist/bin/chunks/time-37F5EBPK.js +0 -14
- package/dist/bin/chunks/xan-5HNHTFMB.js +0 -140
- package/dist/bin/shell/chunks/alias-EGIS5LUE.js +0 -7
- package/dist/bin/shell/chunks/awk2-GFEJOWML.js +0 -21
- package/dist/bin/shell/chunks/bash-PGDTHIM2.js +0 -6
- package/dist/bin/shell/chunks/chunk-26Q3PZQ6.js +0 -2
- package/dist/bin/shell/chunks/chunk-FSAGDARS.js +0 -74
- package/dist/bin/shell/chunks/chunk-IRUD2E3M.js +0 -17
- package/dist/bin/shell/chunks/chunk-KD3EODLB.js +0 -6
- package/dist/bin/shell/chunks/chunk-TA7RUHGQ.js +0 -4
- package/dist/bin/shell/chunks/chunk-UUQYHLBO.js +0 -10
- package/dist/bin/shell/chunks/env-7A4MH7BJ.js +0 -9
- package/dist/bin/shell/chunks/expansion-BOR3ELLC.js +0 -2
- package/dist/bin/shell/chunks/expr-RMGXYNQJ.js +0 -5
- package/dist/bin/shell/chunks/find-PHDZK64M.js +0 -11
- package/dist/bin/shell/chunks/history-G5C2J2OY.js +0 -3
- package/dist/bin/shell/chunks/rg-RSDLLECO.js +0 -33
- package/dist/bin/shell/chunks/time-37F5EBPK.js +0 -14
- package/dist/bin/shell/chunks/xan-5HNHTFMB.js +0 -140
- package/dist/bundle/chunks/alias-ATFBB6D2.js +0 -6
- package/dist/bundle/chunks/awk2-6FBZTP57.js +0 -20
- package/dist/bundle/chunks/bash-OLRNM52U.js +0 -5
- package/dist/bundle/chunks/chunk-3AWP5CWK.js +0 -73
- package/dist/bundle/chunks/chunk-A263W2RD.js +0 -9
- package/dist/bundle/chunks/chunk-CXEWLFNE.js +0 -16
- package/dist/bundle/chunks/chunk-CZPA5RBA.js +0 -5
- package/dist/bundle/chunks/chunk-UJMN5NLH.js +0 -1
- package/dist/bundle/chunks/chunk-ZVV5VXYZ.js +0 -3
- package/dist/bundle/chunks/env-2UI6XINU.js +0 -8
- package/dist/bundle/chunks/expansion-RIGCFEMA.js +0 -1
- package/dist/bundle/chunks/expr-DG4E7SIS.js +0 -4
- package/dist/bundle/chunks/find-YGMSVGUV.js +0 -10
- package/dist/bundle/chunks/history-MQDK2OPD.js +0 -2
- package/dist/bundle/chunks/rg-SRMB7L6G.js +0 -32
- package/dist/bundle/chunks/time-UWXBG6CS.js +0 -13
- package/dist/bundle/chunks/xan-A6VPI4HJ.js +0 -139
|
@@ -900,96 +900,414 @@ jb_http.request = jb_http._client.request
|
|
|
900
900
|
jb_http.Response = _JbHttpResponse
|
|
901
901
|
sys.modules['jb_http'] = jb_http
|
|
902
902
|
|
|
903
|
-
#
|
|
904
|
-
#
|
|
905
|
-
|
|
906
|
-
|
|
903
|
+
# ============================================================
|
|
904
|
+
# SANDBOX SECURITY SETUP
|
|
905
|
+
# ============================================================
|
|
906
|
+
# Only apply sandbox restrictions once per Pyodide instance
|
|
907
|
+
if not hasattr(builtins, '_jb_sandbox_initialized'):
|
|
908
|
+
builtins._jb_sandbox_initialized = True
|
|
907
909
|
|
|
908
|
-
|
|
909
|
-
|
|
910
|
+
# ------------------------------------------------------------
|
|
911
|
+
# 1. Block dangerous module imports (js, pyodide, pyodide_js, pyodide.ffi)
|
|
912
|
+
# These allow sandbox escape via JavaScript execution
|
|
913
|
+
# ------------------------------------------------------------
|
|
914
|
+
_BLOCKED_MODULES = frozenset({'js', 'pyodide', 'pyodide_js', 'pyodide.ffi'})
|
|
915
|
+
_BLOCKED_PREFIXES = ('js.', 'pyodide.', 'pyodide_js.')
|
|
916
|
+
|
|
917
|
+
# Remove pre-loaded dangerous modules from sys.modules
|
|
918
|
+
for _blocked_mod in list(sys.modules.keys()):
|
|
919
|
+
if _blocked_mod in _BLOCKED_MODULES or any(_blocked_mod.startswith(p) for p in _BLOCKED_PREFIXES):
|
|
920
|
+
del sys.modules[_blocked_mod]
|
|
921
|
+
|
|
922
|
+
# Create a secure callable wrapper that hides introspection attributes
|
|
923
|
+
# This prevents access to __closure__, __kwdefaults__, __globals__, etc.
|
|
924
|
+
def _make_secure_import(orig_import, blocked, prefixes):
|
|
925
|
+
"""Create import function wrapped to block introspection."""
|
|
926
|
+
def _inner(name, globals=None, locals=None, fromlist=(), level=0):
|
|
927
|
+
if name in blocked or any(name.startswith(p) for p in prefixes):
|
|
928
|
+
raise ImportError(f"Module '{name}' is blocked in this sandbox")
|
|
929
|
+
return orig_import(name, globals, locals, fromlist, level)
|
|
930
|
+
|
|
931
|
+
class _SecureImport:
|
|
932
|
+
"""Wrapper that hides function internals from introspection."""
|
|
933
|
+
__slots__ = ()
|
|
934
|
+
def __call__(self, name, globals=None, locals=None, fromlist=(), level=0):
|
|
935
|
+
return _inner(name, globals, locals, fromlist, level)
|
|
936
|
+
def __getattribute__(self, name):
|
|
937
|
+
if name in ('__call__', '__class__'):
|
|
938
|
+
return object.__getattribute__(self, name)
|
|
939
|
+
raise AttributeError(f"'{type(self).__name__}' object has no attribute '{name}'")
|
|
940
|
+
def __repr__(self):
|
|
941
|
+
return '<built-in function __import__>'
|
|
942
|
+
return _SecureImport()
|
|
943
|
+
|
|
944
|
+
builtins.__import__ = _make_secure_import(builtins.__import__, _BLOCKED_MODULES, _BLOCKED_PREFIXES)
|
|
945
|
+
del _BLOCKED_MODULES, _BLOCKED_PREFIXES, _make_secure_import
|
|
946
|
+
|
|
947
|
+
# ------------------------------------------------------------
|
|
948
|
+
# 2. Path redirection helper
|
|
949
|
+
# ------------------------------------------------------------
|
|
950
|
+
def _should_redirect(path):
|
|
951
|
+
"""Check if a path should be redirected to /host."""
|
|
952
|
+
return (isinstance(path, str) and
|
|
953
|
+
path.startswith('/') and
|
|
954
|
+
not path.startswith('/lib') and
|
|
955
|
+
not path.startswith('/proc') and
|
|
956
|
+
not path.startswith('/host'))
|
|
957
|
+
|
|
958
|
+
# ------------------------------------------------------------
|
|
959
|
+
# 3. Secure wrapper factory for file operations
|
|
960
|
+
# ------------------------------------------------------------
|
|
961
|
+
# This creates callable wrappers that hide __closure__, __globals__, etc.
|
|
962
|
+
def _make_secure_wrapper(func, name):
|
|
963
|
+
"""Wrap a function to block introspection attributes."""
|
|
964
|
+
class _SecureWrapper:
|
|
965
|
+
__slots__ = ()
|
|
966
|
+
def __call__(self, *args, **kwargs):
|
|
967
|
+
return func(*args, **kwargs)
|
|
968
|
+
def __getattribute__(self, attr):
|
|
969
|
+
if attr in ('__call__', '__class__'):
|
|
970
|
+
return object.__getattribute__(self, attr)
|
|
971
|
+
raise AttributeError(f"'{type(self).__name__}' object has no attribute '{attr}'")
|
|
972
|
+
def __repr__(self):
|
|
973
|
+
return f'<built-in function {name}>'
|
|
974
|
+
return _SecureWrapper()
|
|
975
|
+
|
|
976
|
+
# ------------------------------------------------------------
|
|
977
|
+
# 4. Redirect file operations to /host (with secure wrappers)
|
|
978
|
+
# ------------------------------------------------------------
|
|
979
|
+
# builtins.open
|
|
980
|
+
_orig_open = builtins.open
|
|
981
|
+
def _redir_open(path, mode='r', *args, **kwargs):
|
|
982
|
+
if _should_redirect(path):
|
|
910
983
|
path = '/host' + path
|
|
911
|
-
return
|
|
912
|
-
builtins.open =
|
|
984
|
+
return _orig_open(path, mode, *args, **kwargs)
|
|
985
|
+
builtins.open = _make_secure_wrapper(_redir_open, 'open')
|
|
913
986
|
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
987
|
+
# os.listdir
|
|
988
|
+
_orig_listdir = os.listdir
|
|
989
|
+
def _redir_listdir(path='.'):
|
|
990
|
+
if _should_redirect(path):
|
|
917
991
|
path = '/host' + path
|
|
918
|
-
return
|
|
919
|
-
os.listdir =
|
|
992
|
+
return _orig_listdir(path)
|
|
993
|
+
os.listdir = _make_secure_wrapper(_redir_listdir, 'listdir')
|
|
920
994
|
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
995
|
+
# os.path.exists
|
|
996
|
+
_orig_exists = os.path.exists
|
|
997
|
+
def _redir_exists(path):
|
|
998
|
+
if _should_redirect(path):
|
|
924
999
|
path = '/host' + path
|
|
925
|
-
return
|
|
926
|
-
os.path.exists =
|
|
1000
|
+
return _orig_exists(path)
|
|
1001
|
+
os.path.exists = _make_secure_wrapper(_redir_exists, 'exists')
|
|
927
1002
|
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1003
|
+
# os.path.isfile
|
|
1004
|
+
_orig_isfile = os.path.isfile
|
|
1005
|
+
def _redir_isfile(path):
|
|
1006
|
+
if _should_redirect(path):
|
|
931
1007
|
path = '/host' + path
|
|
932
|
-
return
|
|
933
|
-
os.path.isfile =
|
|
1008
|
+
return _orig_isfile(path)
|
|
1009
|
+
os.path.isfile = _make_secure_wrapper(_redir_isfile, 'isfile')
|
|
934
1010
|
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
1011
|
+
# os.path.isdir
|
|
1012
|
+
_orig_isdir = os.path.isdir
|
|
1013
|
+
def _redir_isdir(path):
|
|
1014
|
+
if _should_redirect(path):
|
|
938
1015
|
path = '/host' + path
|
|
939
|
-
return
|
|
940
|
-
os.path.isdir =
|
|
1016
|
+
return _orig_isdir(path)
|
|
1017
|
+
os.path.isdir = _make_secure_wrapper(_redir_isdir, 'isdir')
|
|
941
1018
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
1019
|
+
# os.stat
|
|
1020
|
+
_orig_stat = os.stat
|
|
1021
|
+
def _redir_stat(path, *args, **kwargs):
|
|
1022
|
+
if _should_redirect(path):
|
|
945
1023
|
path = '/host' + path
|
|
946
|
-
return
|
|
947
|
-
os.stat =
|
|
1024
|
+
return _orig_stat(path, *args, **kwargs)
|
|
1025
|
+
os.stat = _make_secure_wrapper(_redir_stat, 'stat')
|
|
948
1026
|
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
1027
|
+
# os.mkdir
|
|
1028
|
+
_orig_mkdir = os.mkdir
|
|
1029
|
+
def _redir_mkdir(path, *args, **kwargs):
|
|
1030
|
+
if _should_redirect(path):
|
|
952
1031
|
path = '/host' + path
|
|
953
|
-
return
|
|
954
|
-
os.mkdir =
|
|
1032
|
+
return _orig_mkdir(path, *args, **kwargs)
|
|
1033
|
+
os.mkdir = _make_secure_wrapper(_redir_mkdir, 'mkdir')
|
|
955
1034
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
1035
|
+
# os.makedirs
|
|
1036
|
+
_orig_makedirs = os.makedirs
|
|
1037
|
+
def _redir_makedirs(path, *args, **kwargs):
|
|
1038
|
+
if _should_redirect(path):
|
|
959
1039
|
path = '/host' + path
|
|
960
|
-
return
|
|
961
|
-
os.makedirs =
|
|
1040
|
+
return _orig_makedirs(path, *args, **kwargs)
|
|
1041
|
+
os.makedirs = _make_secure_wrapper(_redir_makedirs, 'makedirs')
|
|
962
1042
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
1043
|
+
# os.remove
|
|
1044
|
+
_orig_remove = os.remove
|
|
1045
|
+
def _redir_remove(path, *args, **kwargs):
|
|
1046
|
+
if _should_redirect(path):
|
|
966
1047
|
path = '/host' + path
|
|
967
|
-
return
|
|
968
|
-
os.remove =
|
|
1048
|
+
return _orig_remove(path, *args, **kwargs)
|
|
1049
|
+
os.remove = _make_secure_wrapper(_redir_remove, 'remove')
|
|
969
1050
|
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
1051
|
+
# os.rmdir
|
|
1052
|
+
_orig_rmdir = os.rmdir
|
|
1053
|
+
def _redir_rmdir(path, *args, **kwargs):
|
|
1054
|
+
if _should_redirect(path):
|
|
973
1055
|
path = '/host' + path
|
|
974
|
-
return
|
|
975
|
-
os.rmdir =
|
|
1056
|
+
return _orig_rmdir(path, *args, **kwargs)
|
|
1057
|
+
os.rmdir = _make_secure_wrapper(_redir_rmdir, 'rmdir')
|
|
976
1058
|
|
|
977
|
-
#
|
|
978
|
-
|
|
979
|
-
def
|
|
980
|
-
cwd =
|
|
1059
|
+
# os.getcwd - strip /host prefix
|
|
1060
|
+
_orig_getcwd = os.getcwd
|
|
1061
|
+
def _redir_getcwd():
|
|
1062
|
+
cwd = _orig_getcwd()
|
|
981
1063
|
if cwd.startswith('/host'):
|
|
982
1064
|
return cwd[5:] # Strip '/host' prefix
|
|
983
1065
|
return cwd
|
|
984
|
-
os.getcwd =
|
|
1066
|
+
os.getcwd = _make_secure_wrapper(_redir_getcwd, 'getcwd')
|
|
1067
|
+
|
|
1068
|
+
# os.chdir
|
|
1069
|
+
_orig_chdir = os.chdir
|
|
1070
|
+
def _redir_chdir(path):
|
|
1071
|
+
if _should_redirect(path):
|
|
1072
|
+
path = '/host' + path
|
|
1073
|
+
return _orig_chdir(path)
|
|
1074
|
+
os.chdir = _make_secure_wrapper(_redir_chdir, 'chdir')
|
|
1075
|
+
|
|
1076
|
+
# ------------------------------------------------------------
|
|
1077
|
+
# 5. Additional file operations (glob, walk, scandir, io.open)
|
|
1078
|
+
# ------------------------------------------------------------
|
|
1079
|
+
import glob as _glob_module
|
|
1080
|
+
|
|
1081
|
+
_orig_glob = _glob_module.glob
|
|
1082
|
+
def _redir_glob(pathname, *args, **kwargs):
|
|
1083
|
+
if _should_redirect(pathname):
|
|
1084
|
+
pathname = '/host' + pathname
|
|
1085
|
+
return _orig_glob(pathname, *args, **kwargs)
|
|
1086
|
+
_glob_module.glob = _make_secure_wrapper(_redir_glob, 'glob')
|
|
1087
|
+
|
|
1088
|
+
_orig_iglob = _glob_module.iglob
|
|
1089
|
+
def _redir_iglob(pathname, *args, **kwargs):
|
|
1090
|
+
if _should_redirect(pathname):
|
|
1091
|
+
pathname = '/host' + pathname
|
|
1092
|
+
return _orig_iglob(pathname, *args, **kwargs)
|
|
1093
|
+
_glob_module.iglob = _make_secure_wrapper(_redir_iglob, 'iglob')
|
|
1094
|
+
|
|
1095
|
+
# os.walk (generator - needs special handling)
|
|
1096
|
+
_orig_walk = os.walk
|
|
1097
|
+
def _redir_walk(top, *args, **kwargs):
|
|
1098
|
+
redirected = False
|
|
1099
|
+
if _should_redirect(top):
|
|
1100
|
+
top = '/host' + top
|
|
1101
|
+
redirected = True
|
|
1102
|
+
for dirpath, dirnames, filenames in _orig_walk(top, *args, **kwargs):
|
|
1103
|
+
if redirected and dirpath.startswith('/host'):
|
|
1104
|
+
dirpath = dirpath[5:] if len(dirpath) > 5 else '/'
|
|
1105
|
+
yield dirpath, dirnames, filenames
|
|
1106
|
+
os.walk = _make_secure_wrapper(_redir_walk, 'walk')
|
|
1107
|
+
|
|
1108
|
+
# os.scandir
|
|
1109
|
+
_orig_scandir = os.scandir
|
|
1110
|
+
def _redir_scandir(path='.'):
|
|
1111
|
+
if _should_redirect(path):
|
|
1112
|
+
path = '/host' + path
|
|
1113
|
+
return _orig_scandir(path)
|
|
1114
|
+
os.scandir = _make_secure_wrapper(_redir_scandir, 'scandir')
|
|
1115
|
+
|
|
1116
|
+
# io.open (same secure wrapper as builtins.open)
|
|
1117
|
+
import io as _io_module
|
|
1118
|
+
_io_module.open = builtins.open
|
|
1119
|
+
|
|
1120
|
+
# ------------------------------------------------------------
|
|
1121
|
+
# 6. shutil file operations
|
|
1122
|
+
# ------------------------------------------------------------
|
|
1123
|
+
import shutil as _shutil_module
|
|
1124
|
+
|
|
1125
|
+
# shutil.copy(src, dst)
|
|
1126
|
+
_orig_shutil_copy = _shutil_module.copy
|
|
1127
|
+
def _redir_shutil_copy(src, dst, *args, **kwargs):
|
|
1128
|
+
if _should_redirect(src):
|
|
1129
|
+
src = '/host' + src
|
|
1130
|
+
if _should_redirect(dst):
|
|
1131
|
+
dst = '/host' + dst
|
|
1132
|
+
return _orig_shutil_copy(src, dst, *args, **kwargs)
|
|
1133
|
+
_shutil_module.copy = _make_secure_wrapper(_redir_shutil_copy, 'copy')
|
|
1134
|
+
|
|
1135
|
+
# shutil.copy2(src, dst)
|
|
1136
|
+
_orig_shutil_copy2 = _shutil_module.copy2
|
|
1137
|
+
def _redir_shutil_copy2(src, dst, *args, **kwargs):
|
|
1138
|
+
if _should_redirect(src):
|
|
1139
|
+
src = '/host' + src
|
|
1140
|
+
if _should_redirect(dst):
|
|
1141
|
+
dst = '/host' + dst
|
|
1142
|
+
return _orig_shutil_copy2(src, dst, *args, **kwargs)
|
|
1143
|
+
_shutil_module.copy2 = _make_secure_wrapper(_redir_shutil_copy2, 'copy2')
|
|
1144
|
+
|
|
1145
|
+
# shutil.copyfile(src, dst)
|
|
1146
|
+
_orig_shutil_copyfile = _shutil_module.copyfile
|
|
1147
|
+
def _redir_shutil_copyfile(src, dst, *args, **kwargs):
|
|
1148
|
+
if _should_redirect(src):
|
|
1149
|
+
src = '/host' + src
|
|
1150
|
+
if _should_redirect(dst):
|
|
1151
|
+
dst = '/host' + dst
|
|
1152
|
+
return _orig_shutil_copyfile(src, dst, *args, **kwargs)
|
|
1153
|
+
_shutil_module.copyfile = _make_secure_wrapper(_redir_shutil_copyfile, 'copyfile')
|
|
985
1154
|
|
|
986
|
-
#
|
|
987
|
-
|
|
988
|
-
def
|
|
989
|
-
if
|
|
1155
|
+
# shutil.copytree(src, dst)
|
|
1156
|
+
_orig_shutil_copytree = _shutil_module.copytree
|
|
1157
|
+
def _redir_shutil_copytree(src, dst, *args, **kwargs):
|
|
1158
|
+
if _should_redirect(src):
|
|
1159
|
+
src = '/host' + src
|
|
1160
|
+
if _should_redirect(dst):
|
|
1161
|
+
dst = '/host' + dst
|
|
1162
|
+
return _orig_shutil_copytree(src, dst, *args, **kwargs)
|
|
1163
|
+
_shutil_module.copytree = _make_secure_wrapper(_redir_shutil_copytree, 'copytree')
|
|
1164
|
+
|
|
1165
|
+
# shutil.move(src, dst)
|
|
1166
|
+
_orig_shutil_move = _shutil_module.move
|
|
1167
|
+
def _redir_shutil_move(src, dst, *args, **kwargs):
|
|
1168
|
+
if _should_redirect(src):
|
|
1169
|
+
src = '/host' + src
|
|
1170
|
+
if _should_redirect(dst):
|
|
1171
|
+
dst = '/host' + dst
|
|
1172
|
+
return _orig_shutil_move(src, dst, *args, **kwargs)
|
|
1173
|
+
_shutil_module.move = _make_secure_wrapper(_redir_shutil_move, 'move')
|
|
1174
|
+
|
|
1175
|
+
# shutil.rmtree(path)
|
|
1176
|
+
_orig_shutil_rmtree = _shutil_module.rmtree
|
|
1177
|
+
def _redir_shutil_rmtree(path, *args, **kwargs):
|
|
1178
|
+
if _should_redirect(path):
|
|
990
1179
|
path = '/host' + path
|
|
991
|
-
return
|
|
992
|
-
|
|
1180
|
+
return _orig_shutil_rmtree(path, *args, **kwargs)
|
|
1181
|
+
_shutil_module.rmtree = _make_secure_wrapper(_redir_shutil_rmtree, 'rmtree')
|
|
1182
|
+
|
|
1183
|
+
# ------------------------------------------------------------
|
|
1184
|
+
# 7. pathlib.Path - redirect path resolution
|
|
1185
|
+
# ------------------------------------------------------------
|
|
1186
|
+
from pathlib import Path, PurePosixPath
|
|
1187
|
+
|
|
1188
|
+
def _redirect_path(p):
|
|
1189
|
+
"""Convert a Path to redirect /absolute paths to /host."""
|
|
1190
|
+
s = str(p)
|
|
1191
|
+
if _should_redirect(s):
|
|
1192
|
+
return Path('/host' + s)
|
|
1193
|
+
return p
|
|
1194
|
+
|
|
1195
|
+
# Helper to create method wrappers for Path
|
|
1196
|
+
def _wrap_path_method(orig_method, name):
|
|
1197
|
+
def wrapper(self, *args, **kwargs):
|
|
1198
|
+
redirected = _redirect_path(self)
|
|
1199
|
+
return getattr(redirected, '_orig_' + name)(*args, **kwargs)
|
|
1200
|
+
return wrapper
|
|
1201
|
+
|
|
1202
|
+
# Store original methods with _orig_ prefix, then replace with redirecting versions
|
|
1203
|
+
# Path.stat()
|
|
1204
|
+
Path._orig_stat = Path.stat
|
|
1205
|
+
def _path_stat(self, *args, **kwargs):
|
|
1206
|
+
return _redirect_path(self)._orig_stat(*args, **kwargs)
|
|
1207
|
+
Path.stat = _path_stat
|
|
1208
|
+
|
|
1209
|
+
# Path.exists()
|
|
1210
|
+
Path._orig_exists = Path.exists
|
|
1211
|
+
def _path_exists(self):
|
|
1212
|
+
return _redirect_path(self)._orig_exists()
|
|
1213
|
+
Path.exists = _path_exists
|
|
1214
|
+
|
|
1215
|
+
# Path.is_file()
|
|
1216
|
+
Path._orig_is_file = Path.is_file
|
|
1217
|
+
def _path_is_file(self):
|
|
1218
|
+
return _redirect_path(self)._orig_is_file()
|
|
1219
|
+
Path.is_file = _path_is_file
|
|
1220
|
+
|
|
1221
|
+
# Path.is_dir()
|
|
1222
|
+
Path._orig_is_dir = Path.is_dir
|
|
1223
|
+
def _path_is_dir(self):
|
|
1224
|
+
return _redirect_path(self)._orig_is_dir()
|
|
1225
|
+
Path.is_dir = _path_is_dir
|
|
1226
|
+
|
|
1227
|
+
# Path.open()
|
|
1228
|
+
Path._orig_open = Path.open
|
|
1229
|
+
def _path_open(self, *args, **kwargs):
|
|
1230
|
+
return _redirect_path(self)._orig_open(*args, **kwargs)
|
|
1231
|
+
Path.open = _path_open
|
|
1232
|
+
|
|
1233
|
+
# Path.read_text()
|
|
1234
|
+
Path._orig_read_text = Path.read_text
|
|
1235
|
+
def _path_read_text(self, *args, **kwargs):
|
|
1236
|
+
return _redirect_path(self)._orig_read_text(*args, **kwargs)
|
|
1237
|
+
Path.read_text = _path_read_text
|
|
1238
|
+
|
|
1239
|
+
# Path.read_bytes()
|
|
1240
|
+
Path._orig_read_bytes = Path.read_bytes
|
|
1241
|
+
def _path_read_bytes(self):
|
|
1242
|
+
return _redirect_path(self)._orig_read_bytes()
|
|
1243
|
+
Path.read_bytes = _path_read_bytes
|
|
1244
|
+
|
|
1245
|
+
# Path.write_text()
|
|
1246
|
+
Path._orig_write_text = Path.write_text
|
|
1247
|
+
def _path_write_text(self, *args, **kwargs):
|
|
1248
|
+
return _redirect_path(self)._orig_write_text(*args, **kwargs)
|
|
1249
|
+
Path.write_text = _path_write_text
|
|
1250
|
+
|
|
1251
|
+
# Path.write_bytes()
|
|
1252
|
+
Path._orig_write_bytes = Path.write_bytes
|
|
1253
|
+
def _path_write_bytes(self, data):
|
|
1254
|
+
return _redirect_path(self)._orig_write_bytes(data)
|
|
1255
|
+
Path.write_bytes = _path_write_bytes
|
|
1256
|
+
|
|
1257
|
+
# Path.mkdir()
|
|
1258
|
+
Path._orig_mkdir = Path.mkdir
|
|
1259
|
+
def _path_mkdir(self, *args, **kwargs):
|
|
1260
|
+
return _redirect_path(self)._orig_mkdir(*args, **kwargs)
|
|
1261
|
+
Path.mkdir = _path_mkdir
|
|
1262
|
+
|
|
1263
|
+
# Path.rmdir()
|
|
1264
|
+
Path._orig_rmdir = Path.rmdir
|
|
1265
|
+
def _path_rmdir(self):
|
|
1266
|
+
return _redirect_path(self)._orig_rmdir()
|
|
1267
|
+
Path.rmdir = _path_rmdir
|
|
1268
|
+
|
|
1269
|
+
# Path.unlink()
|
|
1270
|
+
Path._orig_unlink = Path.unlink
|
|
1271
|
+
def _path_unlink(self, *args, **kwargs):
|
|
1272
|
+
return _redirect_path(self)._orig_unlink(*args, **kwargs)
|
|
1273
|
+
Path.unlink = _path_unlink
|
|
1274
|
+
|
|
1275
|
+
# Path.iterdir()
|
|
1276
|
+
Path._orig_iterdir = Path.iterdir
|
|
1277
|
+
def _path_iterdir(self):
|
|
1278
|
+
redirected = _redirect_path(self)
|
|
1279
|
+
for p in redirected._orig_iterdir():
|
|
1280
|
+
# Strip /host prefix from results
|
|
1281
|
+
s = str(p)
|
|
1282
|
+
if s.startswith('/host'):
|
|
1283
|
+
yield Path(s[5:])
|
|
1284
|
+
else:
|
|
1285
|
+
yield p
|
|
1286
|
+
Path.iterdir = _path_iterdir
|
|
1287
|
+
|
|
1288
|
+
# Path.glob()
|
|
1289
|
+
Path._orig_glob = Path.glob
|
|
1290
|
+
def _path_glob(self, pattern):
|
|
1291
|
+
redirected = _redirect_path(self)
|
|
1292
|
+
for p in redirected._orig_glob(pattern):
|
|
1293
|
+
s = str(p)
|
|
1294
|
+
if s.startswith('/host'):
|
|
1295
|
+
yield Path(s[5:])
|
|
1296
|
+
else:
|
|
1297
|
+
yield p
|
|
1298
|
+
Path.glob = _path_glob
|
|
1299
|
+
|
|
1300
|
+
# Path.rglob()
|
|
1301
|
+
Path._orig_rglob = Path.rglob
|
|
1302
|
+
def _path_rglob(self, pattern):
|
|
1303
|
+
redirected = _redirect_path(self)
|
|
1304
|
+
for p in redirected._orig_rglob(pattern):
|
|
1305
|
+
s = str(p)
|
|
1306
|
+
if s.startswith('/host'):
|
|
1307
|
+
yield Path(s[5:])
|
|
1308
|
+
else:
|
|
1309
|
+
yield p
|
|
1310
|
+
Path.rglob = _path_rglob
|
|
993
1311
|
|
|
994
1312
|
# Set cwd to host mount
|
|
995
1313
|
os.chdir('/host' + ${JSON.stringify(input.cwd)})
|