just-bash 2.11.4 → 2.11.6
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/chunk-4QM2TCNV.js +2 -0
- package/dist/bin/{shell/chunks/chunk-X4GRWTSZ.js → chunks/chunk-ISOXAKGQ.js} +58 -58
- package/dist/bin/chunks/chunk-LOJMXC4F.js +5 -0
- package/dist/bin/{shell/chunks/date-6VDN5QZ5.js → chunks/date-WUPBL2TL.js} +1 -1
- package/dist/bin/{shell/chunks/expansion-LT2QL7LY.js → chunks/expansion-AMH5BAVV.js} +1 -1
- package/dist/bin/chunks/{flag-coverage-WM63KT7D.js → flag-coverage-23SVOOPG.js} +1 -1
- package/dist/bin/chunks/python3-UK6DVXEU.js +14 -0
- package/dist/bin/chunks/worker.js +226 -2
- package/dist/bin/just-bash.js +239 -239
- package/dist/bin/shell/chunks/chunk-4QM2TCNV.js +2 -0
- package/dist/bin/{chunks/chunk-X4GRWTSZ.js → shell/chunks/chunk-ISOXAKGQ.js} +58 -58
- package/dist/bin/shell/chunks/chunk-LOJMXC4F.js +5 -0
- package/dist/bin/{chunks/date-6VDN5QZ5.js → shell/chunks/date-WUPBL2TL.js} +1 -1
- package/dist/bin/{chunks/expansion-LT2QL7LY.js → shell/chunks/expansion-AMH5BAVV.js} +1 -1
- package/dist/bin/shell/chunks/{flag-coverage-WM63KT7D.js → flag-coverage-23SVOOPG.js} +1 -1
- package/dist/bin/shell/chunks/python3-UK6DVXEU.js +14 -0
- package/dist/bin/shell/shell.js +267 -266
- package/dist/bundle/browser.js +544 -544
- package/dist/bundle/chunks/chunk-D7MEQ3VN.js +4 -0
- package/dist/bundle/chunks/{chunk-YSCUI42G.js → chunk-V4CDPGZH.js} +58 -58
- package/dist/bundle/chunks/chunk-YYAPW4OA.js +1 -0
- package/dist/bundle/chunks/{date-FT2P5UCQ.js → date-DD7FVA2V.js} +1 -1
- package/dist/bundle/chunks/{expansion-HFUNFLDT.js → expansion-5HXXJ2SG.js} +1 -1
- package/dist/bundle/chunks/{flag-coverage-H2IQM6DS.js → flag-coverage-YHMPSZHK.js} +1 -1
- package/dist/bundle/chunks/python3-W2D6SNQF.js +13 -0
- package/dist/bundle/chunks/worker.js +226 -2
- package/dist/bundle/index.js +181 -181
- package/dist/fs/real-fs-utils.d.ts +3 -1
- package/dist/fs/sanitize-error.d.ts +16 -0
- package/dist/limits.d.ts +2 -0
- package/dist/parser/lexer.d.ts +6 -1
- package/dist/parser/parser.d.ts +3 -3
- package/package.json +1 -1
- package/dist/bin/chunks/chunk-IY3BUFJK.js +0 -5
- package/dist/bin/chunks/python3-ZWX5SFJ3.js +0 -14
- package/dist/bin/shell/chunks/chunk-IY3BUFJK.js +0 -5
- package/dist/bin/shell/chunks/python3-ZWX5SFJ3.js +0 -14
- package/dist/bundle/chunks/chunk-OCK72LWW.js +0 -4
- package/dist/bundle/chunks/python3-SKZGHYDO.js +0 -13
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function d(t){if(!t)return t;let e=t.replace(/\n\s+at\s.*/g,"");return e=e.replace(/(?:\/(?:Users|home|private|var|opt|Library|System|usr|etc|tmp|nix|snap))\b[^\s'",)}\]:]*/g,"<path>"),e=e.replace(/[A-Z]:\\[^\s'",)}\]:]+/g,"<path>"),e}import*as o from"node:fs";import*as r from"node:path";function y(t){if(!t||t==="/")return"/";let e=t.endsWith("/")&&t!=="/"?t.slice(0,-1):t;e.startsWith("/")||(e=`/${e}`);let n=e.split("/").filter(i=>i&&i!=="."),s=[];for(let i of n)i===".."?s.pop():s.push(i);return`/${s.join("/")}`||"/"}function f(t,e){return t===e||t.startsWith(`${e}/`)}function a(t,e){try{let n=o.realpathSync(t);return f(n,e)?n:null}catch(n){if(n.code==="ENOENT"){let s=r.dirname(t);if(s===t)return null;let i=a(s,e);if(i===null)return null;try{if(o.lstatSync(t).isSymbolicLink()){let l=o.readlinkSync(t),u=r.isAbsolute(l)?l:r.resolve(r.dirname(t),l);if(a(u,e)===null)return null}}catch{}return r.join(i,r.basename(t))}return null}}function v(t,e,n){let s=a(t,n);if(s===null)return null;let i=r.resolve(t),c=i.slice(e.length),l=s.slice(n.length);if(c!==l)return null;try{if(o.lstatSync(i).isSymbolicLink())return null}catch{}return s}function m(t,e){if(!o.existsSync(t))throw new Error(`${e} root does not exist`);if(!o.statSync(t).isDirectory())throw new Error(`${e} root is not a directory`)}function S(t,e){if(t.includes("\0"))throw new Error(`ENOENT: path contains null byte, ${e} '${t}'`)}function x(t,e){if(!r.isAbsolute(t))return{withinRoot:!0,relativePath:t};let n;try{n=o.realpathSync(t)}catch{n=r.resolve(t)}return f(n,e)?{withinRoot:!0,relativePath:n.slice(e.length)||"/"}:{withinRoot:!1,safeName:r.basename(t)}}export{d as a,y as b,f as c,a as d,v as e,m as f,S as g,x as h};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a,b}from"./chunk-
|
|
1
|
+
import{a,b}from"./chunk-D7MEQ3VN.js";import"./chunk-74CEPOFO.js";import"./chunk-DXB73IDG.js";export{a as dateCommand,b as flagsForFuzzing};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{A as c,B as d,C as e,I as f,J as g,K as h,L as i,M as j,N as k,O as l,y as a,z as b}from"./chunk-
|
|
1
|
+
import{A as c,B as d,C as e,I as f,J as g,K as h,L as i,M as j,N as k,O as l,y as a,z as b}from"./chunk-V4CDPGZH.js";import"./chunk-YNYSPYQ5.js";import"./chunk-PSW6BMXW.js";import"./chunk-NUFRM6SI.js";import"./chunk-DXB73IDG.js";export{d as escapeGlobChars,e as escapeRegexChars,l as expandRedirectTarget,g as expandWord,i as expandWordForPattern,h as expandWordForRegex,j as expandWordWithGlob,a as getArrayElements,c as getVariable,k as hasQuotedMultiValueAt,b as isArray,f as isWordFullyQuoted};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as yr}from"./chunk-VZWXH2PZ.js";import{b as Ar}from"./chunk-XMDVFEVC.js";import{b as $r}from"./chunk-JI3KJ32H.js";import"./chunk-F55TLFGB.js";import"./chunk-SYMJJMQ4.js";import{b as Sr}from"./chunk-HDZ4QEVJ.js";import{b as wr}from"./chunk-MDLLFABN.js";import{b as xr}from"./chunk-ZKLK6C7H.js";import{b as vr}from"./chunk-UYGR3CFC.js";import{b as kr}from"./chunk-NQOQ2Q77.js";import{b as qr}from"./chunk-4HHKTUW3.js";import{b as Cr}from"./chunk-HJQJAYMS.js";import{b as br}from"./chunk-PP6PSHAB.js";import{d as Ir,e as Mr,f as jr}from"./chunk-DZ33S2U7.js";import{b as tr}from"./chunk-XNL7YAHW.js";import{b as lr}from"./chunk-CSBFBYLD.js";import{b as ur}from"./chunk-A7A2DBEE.js";import{b as pr}from"./chunk-U7QI5ZS5.js";import{b as er}from"./chunk-APT7OOP2.js";import{b as dr}from"./chunk-XKQRETAK.js";import{b as cr}from"./chunk-5V6VZH6T.js";import"./chunk-EIZGF4BS.js";import{b as hr}from"./chunk-CR5AFCPT.js";import{c as or,d as ar}from"./chunk-R6QSAL5T.js";import{b as sr}from"./chunk-LL3S3NLB.js";import{c as ir,d as gr}from"./chunk-JP44OYZS.js";import{b as mr}from"./chunk-2OCD45J4.js";import"./chunk-FRDGR5VK.js";import"./chunk-7MKBHGLS.js";import{b as Fr}from"./chunk-IBFD7QQD.js";import{b as zr}from"./chunk-TLSUDHID.js";import{b as fr}from"./chunk-
|
|
1
|
+
import{b as yr}from"./chunk-VZWXH2PZ.js";import{b as Ar}from"./chunk-XMDVFEVC.js";import{b as $r}from"./chunk-JI3KJ32H.js";import"./chunk-F55TLFGB.js";import"./chunk-SYMJJMQ4.js";import{b as Sr}from"./chunk-HDZ4QEVJ.js";import{b as wr}from"./chunk-MDLLFABN.js";import{b as xr}from"./chunk-ZKLK6C7H.js";import{b as vr}from"./chunk-UYGR3CFC.js";import{b as kr}from"./chunk-NQOQ2Q77.js";import{b as qr}from"./chunk-4HHKTUW3.js";import{b as Cr}from"./chunk-HJQJAYMS.js";import{b as br}from"./chunk-PP6PSHAB.js";import{d as Ir,e as Mr,f as jr}from"./chunk-DZ33S2U7.js";import{b as tr}from"./chunk-XNL7YAHW.js";import{b as lr}from"./chunk-CSBFBYLD.js";import{b as ur}from"./chunk-A7A2DBEE.js";import{b as pr}from"./chunk-U7QI5ZS5.js";import{b as er}from"./chunk-APT7OOP2.js";import{b as dr}from"./chunk-XKQRETAK.js";import{b as cr}from"./chunk-5V6VZH6T.js";import"./chunk-EIZGF4BS.js";import{b as hr}from"./chunk-CR5AFCPT.js";import{c as or,d as ar}from"./chunk-R6QSAL5T.js";import{b as sr}from"./chunk-LL3S3NLB.js";import{c as ir,d as gr}from"./chunk-JP44OYZS.js";import{b as mr}from"./chunk-2OCD45J4.js";import"./chunk-FRDGR5VK.js";import"./chunk-7MKBHGLS.js";import{b as Fr}from"./chunk-IBFD7QQD.js";import{b as zr}from"./chunk-TLSUDHID.js";import{b as fr}from"./chunk-D7MEQ3VN.js";import{b as nr}from"./chunk-WMLBQOWO.js";import{b as R}from"./chunk-ALLTKNUZ.js";import{b as U}from"./chunk-4Q4SM6WR.js";import{b as V}from"./chunk-XVDPCNWR.js";import{b as W}from"./chunk-K3PAWJ7V.js";import{c as X,d as Y}from"./chunk-OGDTSM2Q.js";import{c as Z,d as _}from"./chunk-VOBGTVA6.js";import{b as N}from"./chunk-NCNPKYJZ.js";import{b as rr}from"./chunk-SXR3EI72.js";import{b as G}from"./chunk-VJFXDYWH.js";import{b as H}from"./chunk-PYSFUGCK.js";import{b as J}from"./chunk-VYOJP4TV.js";import{b as K}from"./chunk-KTGH7NTP.js";import{b as L}from"./chunk-LWEGUNWT.js";import{b as O}from"./chunk-A7ICOL4V.js";import{b as P}from"./chunk-55VFSPNA.js";import{b as Q}from"./chunk-YYB54I7F.js";import{b as y}from"./chunk-7C6RBHP3.js";import{b as A}from"./chunk-Z7JVV2SM.js";import{b as $}from"./chunk-6NY2AP72.js";import{b as S}from"./chunk-JVPRLUMK.js";import{b as T}from"./chunk-X6JMGGW2.js";import{b as B}from"./chunk-QCDB2VPH.js";import{b as D}from"./chunk-F23WWYKW.js";import{b as E}from"./chunk-D4J545R4.js";import{b as w}from"./chunk-DCAAORBQ.js";import{b as x}from"./chunk-GXVXFKBA.js";import{b as v}from"./chunk-OFJTSXN6.js";import{d as k,e as q,f as C}from"./chunk-S6BBC45K.js";import"./chunk-IJXFPKNC.js";import{b}from"./chunk-QOENL5UZ.js";import"./chunk-VLGZJRPG.js";import{b as I}from"./chunk-MZLOTDD7.js";import{b as M}from"./chunk-3KWUDRIP.js";import{b as j}from"./chunk-KAEMRWOH.js";import{b as t}from"./chunk-27LMNKBP.js";import{b as l}from"./chunk-NUYSJFDK.js";import{b as u}from"./chunk-A4JSPFCI.js";import{b as p}from"./chunk-SL4FN3A5.js";import{b as e}from"./chunk-GZ2N3SXD.js";import{b as d}from"./chunk-A4HU7SVR.js";import{b as c}from"./chunk-IKZ5LEGB.js";import{b as h}from"./chunk-64BAICW3.js";import"./chunk-HDQ56CKY.js";import"./chunk-OJDRYQWQ.js";import"./chunk-YNYSPYQ5.js";import{b as i}from"./chunk-GCTKCWKD.js";import{b as g}from"./chunk-7DBA735O.js";import"./chunk-7L36YK2X.js";import{b as m}from"./chunk-L4KW73FJ.js";import"./chunk-EEXR5ZDP.js";import"./chunk-PSW6BMXW.js";import{b as F}from"./chunk-KY5VPZXG.js";import"./chunk-NUFRM6SI.js";import{b as z}from"./chunk-XZ3MZS57.js";import{b as f}from"./chunk-OCS6LSEM.js";import"./chunk-HWKDQ44K.js";import{b as n}from"./chunk-OCLXQMOG.js";import"./chunk-44UOCSGV.js";import"./chunk-74CEPOFO.js";import"./chunk-DXB73IDG.js";var Er=[i,g,m,F,z,f,n,t,l,u,p,e,d,c,h,w,x,v,k,q,C,b,I,M,j,y,A,$,S,T,B,D,E,G,H,J,K,L,O,P,Q,R,U,V,W,X,Y,Z,_,N,rr,or,ar,sr,ir,gr,mr,Fr,zr,fr,nr,tr,lr,ur,pr,er,dr,cr,hr,wr,xr,vr,kr,qr,Cr,br,Ir,Mr,jr,yr,Ar,$r,Sr];function Tr(){return Er}var Br=new Map;for(let r of Tr())Br.set(r.name,new Set(r.flags.map(o=>o.flag)));function Fa(r,o,Dr){let a=Br.get(o);if(!(!a||a.size===0))for(let s of Dr)a.has(s)&&r.hit(`cmd:flag:${o}:${s}`)}export{Fa as emitFlagCoverage};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{a as f}from"./chunk-YYAPW4OA.js";import{a as O}from"./chunk-OJDRYQWQ.js";import{a as D,b as C}from"./chunk-74CEPOFO.js";import"./chunk-DXB73IDG.js";import{fileURLToPath as N}from"node:url";import{Worker as V}from"node:worker_threads";var h={NOOP:0,READ_FILE:1,WRITE_FILE:2,STAT:3,READDIR:4,MKDIR:5,RM:6,EXISTS:7,APPEND_FILE:8,SYMLINK:9,READLINK:10,LSTAT:11,CHMOD:12,REALPATH:13,WRITE_STDOUT:100,WRITE_STDERR:101,EXIT:102,HTTP_REQUEST:200},n={PENDING:0,READY:1,SUCCESS:2,ERROR:3},u={NONE:0,NOT_FOUND:1,IS_DIRECTORY:2,NOT_DIRECTORY:3,EXISTS:4,PERMISSION_DENIED:5,INVALID_PATH:6,IO_ERROR:7,TIMEOUT:8,NETWORK_ERROR:9,NETWORK_NOT_CONFIGURED:10},i={OP_CODE:0,STATUS:4,PATH_LENGTH:8,DATA_LENGTH:12,RESULT_LENGTH:16,ERROR_CODE:20,FLAGS:24,MODE:28,PATH_BUFFER:32,DATA_BUFFER:4128},p={CONTROL_REGION:32,PATH_BUFFER:4096,DATA_BUFFER:1048576,TOTAL:1052704},R={NONE:0,RECURSIVE:1,FORCE:2,MKDIR_RECURSIVE:1},c={IS_FILE:0,IS_DIRECTORY:1,IS_SYMLINK:2,MODE:4,SIZE:8,MTIME:16,TOTAL:24};function _(){return new SharedArrayBuffer(p.TOTAL)}var w=class{int32View;uint8View;dataView;constructor(t){this.int32View=new Int32Array(t),this.uint8View=new Uint8Array(t),this.dataView=new DataView(t)}getOpCode(){return Atomics.load(this.int32View,i.OP_CODE/4)}setOpCode(t){Atomics.store(this.int32View,i.OP_CODE/4,t)}getStatus(){return Atomics.load(this.int32View,i.STATUS/4)}setStatus(t){Atomics.store(this.int32View,i.STATUS/4,t)}getPathLength(){return Atomics.load(this.int32View,i.PATH_LENGTH/4)}setPathLength(t){Atomics.store(this.int32View,i.PATH_LENGTH/4,t)}getDataLength(){return Atomics.load(this.int32View,i.DATA_LENGTH/4)}setDataLength(t){Atomics.store(this.int32View,i.DATA_LENGTH/4,t)}getResultLength(){return Atomics.load(this.int32View,i.RESULT_LENGTH/4)}setResultLength(t){Atomics.store(this.int32View,i.RESULT_LENGTH/4,t)}getErrorCode(){return Atomics.load(this.int32View,i.ERROR_CODE/4)}setErrorCode(t){Atomics.store(this.int32View,i.ERROR_CODE/4,t)}getFlags(){return Atomics.load(this.int32View,i.FLAGS/4)}setFlags(t){Atomics.store(this.int32View,i.FLAGS/4,t)}getMode(){return Atomics.load(this.int32View,i.MODE/4)}setMode(t){Atomics.store(this.int32View,i.MODE/4,t)}getPath(){let t=this.getPathLength(),e=this.uint8View.slice(i.PATH_BUFFER,i.PATH_BUFFER+t);return new TextDecoder().decode(e)}setPath(t){let e=new TextEncoder().encode(t);if(e.length>p.PATH_BUFFER)throw new Error(`Path too long: ${e.length} > ${p.PATH_BUFFER}`);this.uint8View.set(e,i.PATH_BUFFER),this.setPathLength(e.length)}getData(){let t=this.getDataLength();return this.uint8View.slice(i.DATA_BUFFER,i.DATA_BUFFER+t)}setData(t){if(t.length>p.DATA_BUFFER)throw new Error(`Data too large: ${t.length} > ${p.DATA_BUFFER}`);this.uint8View.set(t,i.DATA_BUFFER),this.setDataLength(t.length)}getDataAsString(){let t=this.getData();return new TextDecoder().decode(t)}setDataFromString(t){let e=new TextEncoder().encode(t);this.setData(e)}getResult(){let t=this.getResultLength();return this.uint8View.slice(i.DATA_BUFFER,i.DATA_BUFFER+t)}setResult(t){if(t.length>p.DATA_BUFFER)throw new Error(`Result too large: ${t.length} > ${p.DATA_BUFFER}`);this.uint8View.set(t,i.DATA_BUFFER),this.setResultLength(t.length)}getResultAsString(){let t=this.getResult();return new TextDecoder().decode(t)}setResultFromString(t){let e=new TextEncoder().encode(t);this.setResult(e)}encodeStat(t){this.uint8View[i.DATA_BUFFER+c.IS_FILE]=t.isFile?1:0,this.uint8View[i.DATA_BUFFER+c.IS_DIRECTORY]=t.isDirectory?1:0,this.uint8View[i.DATA_BUFFER+c.IS_SYMLINK]=t.isSymbolicLink?1:0,this.dataView.setInt32(i.DATA_BUFFER+c.MODE,t.mode,!0);let e=Math.min(t.size,Number.MAX_SAFE_INTEGER);this.dataView.setFloat64(i.DATA_BUFFER+c.SIZE,e,!0),this.dataView.setFloat64(i.DATA_BUFFER+c.MTIME,t.mtime.getTime(),!0),this.setResultLength(c.TOTAL)}decodeStat(){return{isFile:this.uint8View[i.DATA_BUFFER+c.IS_FILE]===1,isDirectory:this.uint8View[i.DATA_BUFFER+c.IS_DIRECTORY]===1,isSymbolicLink:this.uint8View[i.DATA_BUFFER+c.IS_SYMLINK]===1,mode:this.dataView.getInt32(i.DATA_BUFFER+c.MODE,!0),size:this.dataView.getFloat64(i.DATA_BUFFER+c.SIZE,!0),mtime:new Date(this.dataView.getFloat64(i.DATA_BUFFER+c.MTIME,!0))}}waitForReady(t){return Atomics.wait(this.int32View,i.STATUS/4,n.PENDING,t)}waitForReadyAsync(t){return Atomics.waitAsync(this.int32View,i.STATUS/4,n.PENDING,t)}async waitUntilReady(t){let e=Date.now();for(;;){let s=this.getStatus();if(s===n.READY)return!0;let o=Date.now()-e;if(o>=t)return!1;let a=t-o,d=Atomics.waitAsync(this.int32View,i.STATUS/4,s,a);if(d.async&&await d.value==="timed-out")return!1}}waitForResult(t){return Atomics.wait(this.int32View,i.STATUS/4,n.READY,t)}notify(){return Atomics.notify(this.int32View,i.STATUS/4)}reset(){this.setOpCode(h.NOOP),this.setStatus(n.PENDING),this.setPathLength(0),this.setDataLength(0),this.setResultLength(0),this.setErrorCode(u.NONE),this.setFlags(R.NONE),this.setMode(0)}};var A=class{fs;cwd;secureFetch;protocol;running=!1;output={stdout:"",stderr:"",exitCode:0};constructor(t,e,s,o=void 0){this.fs=e,this.cwd=s,this.secureFetch=o,this.protocol=new w(t)}async run(t){this.running=!0;let e=Date.now();for(;this.running;){let s=Date.now()-e;if(s>=t){this.output.stderr+=`
|
|
2
|
+
python3: execution timeout exceeded
|
|
3
|
+
`,this.output.exitCode=124;break}let o=t-s;if(!await this.protocol.waitUntilReady(o)){this.output.stderr+=`
|
|
4
|
+
python3: execution timeout exceeded
|
|
5
|
+
`,this.output.exitCode=124;break}let d=this.protocol.getOpCode();await this.handleOperation(d),this.protocol.notify()}return this.output}stop(){this.running=!1}async handleOperation(t){try{switch(t){case h.READ_FILE:await this.handleReadFile();break;case h.WRITE_FILE:await this.handleWriteFile();break;case h.STAT:await this.handleStat();break;case h.LSTAT:await this.handleLstat();break;case h.READDIR:await this.handleReaddir();break;case h.MKDIR:await this.handleMkdir();break;case h.RM:await this.handleRm();break;case h.EXISTS:await this.handleExists();break;case h.APPEND_FILE:await this.handleAppendFile();break;case h.SYMLINK:await this.handleSymlink();break;case h.READLINK:await this.handleReadlink();break;case h.CHMOD:await this.handleChmod();break;case h.REALPATH:await this.handleRealpath();break;case h.WRITE_STDOUT:this.handleWriteStdout();break;case h.WRITE_STDERR:this.handleWriteStderr();break;case h.EXIT:this.handleExit();break;case h.HTTP_REQUEST:await this.handleHttpRequest();break;default:this.protocol.setErrorCode(u.IO_ERROR),this.protocol.setStatus(n.ERROR)}}catch(e){this.setErrorFromException(e)}}resolvePath(t){return t.startsWith("/mnt/host/")?t.slice(9):t.startsWith("/mnt/host")?t.slice(9)||"/":this.fs.resolvePath(this.cwd,t)}async handleReadFile(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readFileBuffer(t);this.protocol.setResult(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleWriteFile(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getData();try{await this.fs.writeFile(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleStat(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.stat(t);this.protocol.encodeStat(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleLstat(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.lstat(t);this.protocol.encodeStat(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleReaddir(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readdir(t);this.protocol.setResultFromString(JSON.stringify(e)),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleMkdir(){let t=this.resolvePath(this.protocol.getPath()),s=(this.protocol.getFlags()&R.MKDIR_RECURSIVE)!==0;try{await this.fs.mkdir(t,{recursive:s}),this.protocol.setStatus(n.SUCCESS)}catch(o){this.setErrorFromException(o)}}async handleRm(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getFlags(),s=(e&R.RECURSIVE)!==0,o=(e&R.FORCE)!==0;try{await this.fs.rm(t,{recursive:s,force:o}),this.protocol.setStatus(n.SUCCESS)}catch(a){this.setErrorFromException(a)}}async handleExists(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.exists(t);this.protocol.setResult(new Uint8Array([e?1:0])),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleAppendFile(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getData();try{await this.fs.appendFile(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleSymlink(){let t=this.protocol.getPath(),e=this.protocol.getDataAsString(),s=this.resolvePath(t);try{await this.fs.symlink(e,s),this.protocol.setStatus(n.SUCCESS)}catch(o){this.setErrorFromException(o)}}async handleReadlink(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.readlink(t);this.protocol.setResultFromString(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}async handleChmod(){let t=this.resolvePath(this.protocol.getPath()),e=this.protocol.getMode();try{await this.fs.chmod(t,e),this.protocol.setStatus(n.SUCCESS)}catch(s){this.setErrorFromException(s)}}async handleRealpath(){let t=this.resolvePath(this.protocol.getPath());try{let e=await this.fs.realpath(t);this.protocol.setResultFromString(e),this.protocol.setStatus(n.SUCCESS)}catch(e){this.setErrorFromException(e)}}handleWriteStdout(){let t=this.protocol.getDataAsString();this.output.stdout+=t,this.protocol.setStatus(n.SUCCESS)}handleWriteStderr(){let t=this.protocol.getDataAsString();this.output.stderr+=t,this.protocol.setStatus(n.SUCCESS)}handleExit(){let t=this.protocol.getFlags();this.output.exitCode=t,this.protocol.setStatus(n.SUCCESS),this.running=!1}async handleHttpRequest(){if(!this.secureFetch){this.protocol.setErrorCode(u.NETWORK_NOT_CONFIGURED),this.protocol.setResultFromString("Network access not configured. Enable network in Bash options."),this.protocol.setStatus(n.ERROR);return}let t=this.protocol.getPath(),e=this.protocol.getDataAsString();try{let s=e?JSON.parse(e):{},o=await this.secureFetch(t,{method:s.method,headers:s.headers,body:s.body}),a=JSON.stringify({status:o.status,statusText:o.statusText,headers:o.headers,body:o.body,url:o.url});this.protocol.setResultFromString(a),this.protocol.setStatus(n.SUCCESS)}catch(s){let o=f(s instanceof Error?s.message:String(s));this.protocol.setErrorCode(u.NETWORK_ERROR),this.protocol.setResultFromString(o),this.protocol.setStatus(n.ERROR)}}setErrorFromException(t){let e=t instanceof Error?t.message:String(t),s=f(e),o=u.IO_ERROR,a=e.toLowerCase();a.includes("no such file")||a.includes("not found")||a.includes("enoent")?o=u.NOT_FOUND:a.includes("is a directory")||a.includes("eisdir")?o=u.IS_DIRECTORY:a.includes("not a directory")||a.includes("enotdir")?o=u.NOT_DIRECTORY:a.includes("already exists")||a.includes("eexist")?o=u.EXISTS:(a.includes("permission")||a.includes("eperm")||a.includes("eacces"))&&(o=u.PERMISSION_DENIED),this.protocol.setErrorCode(o),this.protocol.setResultFromString(s),this.protocol.setStatus(n.ERROR)}};var M=3e4,k={name:"python3",summary:"Execute Python code via Pyodide",usage:"python3 [OPTIONS] [-c CODE | -m MODULE | FILE] [ARGS...]",description:["Execute Python code using Pyodide (Python compiled to WebAssembly).","","This command runs Python in a sandboxed environment with access to","the virtual filesystem. Only Pyodide-bundled packages are available."],options:["-c CODE Execute CODE as Python script","-m MODULE Run library module as a script","--version Show Python version","--help Show this help"],examples:['python3 -c "print(1 + 2)"','python3 -c "import sys; print(sys.version)"',"python3 script.py","python3 script.py arg1 arg2",`echo 'print("hello")' | python3`],notes:["Pyodide runs in WebAssembly, so execution may be slower than native Python.","Only packages bundled with Pyodide are available (no pip install).","First execution loads Pyodide (~30MB), subsequent calls are faster.","Maximum execution time is 30 seconds by default."]};function b(r){let t={code:null,module:null,scriptFile:null,showVersion:!1,scriptArgs:[]};if(r.length===0)return t;let e=r.findIndex(s=>!s.startsWith("-")||s==="-"||s==="--");for(let s=0;s<(e===-1?r.length:e);s++){let o=r[s];if(o==="-c")return s+1>=r.length?{stdout:"",stderr:`python3: option requires an argument -- 'c'
|
|
6
|
+
`,exitCode:2}:(t.code=r[s+1],t.scriptArgs=r.slice(s+2),t);if(o==="-m")return s+1>=r.length?{stdout:"",stderr:`python3: option requires an argument -- 'm'
|
|
7
|
+
`,exitCode:2}:(t.module=r[s+1],t.scriptArgs=r.slice(s+2),t);if(o==="--version"||o==="-V")return t.showVersion=!0,t;if(o.startsWith("-")&&o!=="-")return{stdout:"",stderr:`python3: unrecognized option '${o}'
|
|
8
|
+
`,exitCode:2}}if(e!==-1){let s=r[e];s==="--"?e+1<r.length&&(t.scriptFile=r[e+1],t.scriptArgs=r.slice(e+2)):(t.scriptFile=s,t.scriptArgs=r.slice(e+1))}return t}var l=null,g=null,S=[],E=null,B=N(new URL("./worker.js",import.meta.url));function P(){if(E||S.length===0)return;let r=S.shift();if(!r)return;E=r,v().postMessage(E.input)}function v(){return g&&(clearTimeout(g),g=null),l||(l=new V(B),l.on("message",r=>{E&&(E.resolve(r),E=null),S.length>0?P():H()}),l.on("error",r=>{E&&(E.resolve({success:!1,error:r.message}),E=null);for(let t of S)t.resolve({success:!1,error:"Worker crashed"});S.length=0,l=null}),l.on("exit",()=>{l=null}),l)}function H(){g=setTimeout(()=>{l&&!E&&S.length===0&&(l.terminate(),l=null)},5e3)}async function W(r,t,e,s=[]){let o=_(),a=new A(o,t.fs,t.cwd,t.fetch),d=t.limits?.maxPythonTimeoutMs??M,y={sharedBuffer:o,pythonCode:r,cwd:t.cwd,env:O(t.env),args:s,scriptPath:e},I=new Promise(T=>{let U=setTimeout(()=>{T({success:!1,error:`Execution timeout: exceeded ${d}ms limit`})},d),x=L=>{clearTimeout(U),T(L)};S.push({input:y,resolve:x}),P()}),[m,F]=await Promise.all([a.run(d),I.catch(T=>({success:!1,error:T.message}))]);return!F.success&&F.error?{stdout:m.stdout,stderr:`${m.stderr}python3: ${F.error}
|
|
9
|
+
`,exitCode:m.exitCode||1}:m}var G={name:"python3",async execute(r,t){if(C(r))return D(k);let e=b(r);if("exitCode"in e)return e;if(e.showVersion)return{stdout:`Python 3.12.1 (Pyodide)
|
|
10
|
+
`,stderr:"",exitCode:0};let s,o;if(e.code!==null)s=e.code,o="-c";else if(e.module!==null)s=`import runpy; runpy.run_module('${e.module}', run_name='__main__')`,o=e.module;else if(e.scriptFile!==null){let a=t.fs.resolvePath(t.cwd,e.scriptFile);if(!await t.fs.exists(a))return{stdout:"",stderr:`python3: can't open file '${e.scriptFile}': [Errno 2] No such file or directory
|
|
11
|
+
`,exitCode:2};try{s=await t.fs.readFile(a),o=e.scriptFile}catch(d){return{stdout:"",stderr:`python3: can't open file '${e.scriptFile}': ${d.message}
|
|
12
|
+
`,exitCode:2}}}else if(t.stdin.trim())s=t.stdin,o="<stdin>";else return{stdout:"",stderr:`python3: no input provided (use -c CODE, -m MODULE, or provide a script file)
|
|
13
|
+
`,exitCode:2};return W(s,t,o,e.scriptArgs)}},tt={name:"python",async execute(r,t){return G.execute(r,t)}};export{G as python3Command,tt as pythonCommand};
|
|
@@ -87,6 +87,109 @@ function getBlockedGlobals() {
|
|
|
87
87
|
// Note: process.mainModule is handled specially in defense-in-depth-box.ts
|
|
88
88
|
// and worker-defense-in-depth.ts because it may be undefined in ESM contexts
|
|
89
89
|
// but we still want to block both reading and setting it.
|
|
90
|
+
// Process control vectors
|
|
91
|
+
{
|
|
92
|
+
prop: "exit",
|
|
93
|
+
target: process,
|
|
94
|
+
violationType: "process_exit",
|
|
95
|
+
strategy: "throw",
|
|
96
|
+
reason: "process.exit could terminate the interpreter"
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
prop: "abort",
|
|
100
|
+
target: process,
|
|
101
|
+
violationType: "process_exit",
|
|
102
|
+
strategy: "throw",
|
|
103
|
+
reason: "process.abort could crash the interpreter"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
prop: "kill",
|
|
107
|
+
target: process,
|
|
108
|
+
violationType: "process_kill",
|
|
109
|
+
strategy: "throw",
|
|
110
|
+
reason: "process.kill could signal other processes"
|
|
111
|
+
},
|
|
112
|
+
// Privilege escalation vectors
|
|
113
|
+
{
|
|
114
|
+
prop: "setuid",
|
|
115
|
+
target: process,
|
|
116
|
+
violationType: "process_setuid",
|
|
117
|
+
strategy: "throw",
|
|
118
|
+
reason: "process.setuid could escalate privileges"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
prop: "setgid",
|
|
122
|
+
target: process,
|
|
123
|
+
violationType: "process_setuid",
|
|
124
|
+
strategy: "throw",
|
|
125
|
+
reason: "process.setgid could escalate privileges"
|
|
126
|
+
},
|
|
127
|
+
// File permission manipulation
|
|
128
|
+
{
|
|
129
|
+
prop: "umask",
|
|
130
|
+
target: process,
|
|
131
|
+
violationType: "process_umask",
|
|
132
|
+
strategy: "throw",
|
|
133
|
+
reason: "process.umask could modify file creation permissions"
|
|
134
|
+
},
|
|
135
|
+
// Information disclosure vectors
|
|
136
|
+
// Note: process.argv is an array (object) so gets an object proxy
|
|
137
|
+
{
|
|
138
|
+
prop: "argv",
|
|
139
|
+
target: process,
|
|
140
|
+
violationType: "process_argv",
|
|
141
|
+
strategy: "throw",
|
|
142
|
+
reason: "process.argv may contain secrets in CLI arguments"
|
|
143
|
+
},
|
|
144
|
+
// Note: process.execPath is a string primitive, handled specially
|
|
145
|
+
// in defense-in-depth-box.ts and worker-defense-in-depth.ts
|
|
146
|
+
// Note: process.connected is a boolean primitive, handled specially
|
|
147
|
+
// in defense-in-depth-box.ts and worker-defense-in-depth.ts
|
|
148
|
+
// Working directory manipulation
|
|
149
|
+
{
|
|
150
|
+
prop: "chdir",
|
|
151
|
+
target: process,
|
|
152
|
+
violationType: "process_chdir",
|
|
153
|
+
strategy: "throw",
|
|
154
|
+
reason: "process.chdir could confuse the interpreter's CWD tracking"
|
|
155
|
+
},
|
|
156
|
+
// IPC communication vectors (may be undefined in non-IPC contexts)
|
|
157
|
+
{
|
|
158
|
+
prop: "send",
|
|
159
|
+
target: process,
|
|
160
|
+
violationType: "process_send",
|
|
161
|
+
strategy: "throw",
|
|
162
|
+
reason: "process.send could communicate with parent process in IPC contexts"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
prop: "channel",
|
|
166
|
+
target: process,
|
|
167
|
+
violationType: "process_channel",
|
|
168
|
+
strategy: "throw",
|
|
169
|
+
reason: "process.channel could access IPC channel to parent process"
|
|
170
|
+
},
|
|
171
|
+
// Timing side-channel vectors
|
|
172
|
+
{
|
|
173
|
+
prop: "cpuUsage",
|
|
174
|
+
target: process,
|
|
175
|
+
violationType: "process_timing",
|
|
176
|
+
strategy: "throw",
|
|
177
|
+
reason: "process.cpuUsage could enable timing side-channel attacks"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
prop: "memoryUsage",
|
|
181
|
+
target: process,
|
|
182
|
+
violationType: "process_timing",
|
|
183
|
+
strategy: "throw",
|
|
184
|
+
reason: "process.memoryUsage could enable timing side-channel attacks"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
prop: "hrtime",
|
|
188
|
+
target: process,
|
|
189
|
+
violationType: "process_timing",
|
|
190
|
+
strategy: "throw",
|
|
191
|
+
reason: "process.hrtime could enable timing side-channel attacks"
|
|
192
|
+
},
|
|
90
193
|
// We also don't block `require` because:
|
|
91
194
|
// 1. It may not exist in all environments (ESM)
|
|
92
195
|
// 2. import() is the modern escape vector and can't be blocked this way
|
|
@@ -215,8 +318,8 @@ if (!IS_BROWSER) {
|
|
|
215
318
|
const asyncHooks = require3("node:async_hooks");
|
|
216
319
|
AsyncLocalStorageClass = asyncHooks.AsyncLocalStorage;
|
|
217
320
|
} catch (e) {
|
|
218
|
-
console.
|
|
219
|
-
"[DefenseInDepthBox] AsyncLocalStorage not available, defense-in-depth
|
|
321
|
+
console.warn(
|
|
322
|
+
"[DefenseInDepthBox] WARNING: AsyncLocalStorage not available, defense-in-depth security layer is DISABLED. This means script execution will NOT be protected by runtime security patches. Reason:",
|
|
220
323
|
e instanceof Error ? e.message : e
|
|
221
324
|
);
|
|
222
325
|
}
|
|
@@ -524,6 +627,12 @@ var WorkerDefenseInDepth = class {
|
|
|
524
627
|
if (!excludeTypes.has("process_main_module")) {
|
|
525
628
|
this.protectProcessMainModule();
|
|
526
629
|
}
|
|
630
|
+
if (!excludeTypes.has("process_exec_path")) {
|
|
631
|
+
this.protectProcessExecPath();
|
|
632
|
+
}
|
|
633
|
+
if (!excludeTypes.has("process_connected")) {
|
|
634
|
+
this.protectProcessConnected();
|
|
635
|
+
}
|
|
527
636
|
}
|
|
528
637
|
/**
|
|
529
638
|
* Protect against .constructor.constructor escape vector.
|
|
@@ -761,6 +870,121 @@ var WorkerDefenseInDepth = class {
|
|
|
761
870
|
} catch {
|
|
762
871
|
}
|
|
763
872
|
}
|
|
873
|
+
/**
|
|
874
|
+
* Protect process.execPath from being read or set in worker context.
|
|
875
|
+
*
|
|
876
|
+
* process.execPath is a string primitive (not an object), so it cannot be
|
|
877
|
+
* proxied via the normal blocked globals mechanism. We use Object.defineProperty
|
|
878
|
+
* with getter/setter (same pattern as protectProcessMainModule).
|
|
879
|
+
*/
|
|
880
|
+
protectProcessExecPath() {
|
|
881
|
+
if (typeof process === "undefined") return;
|
|
882
|
+
const self = this;
|
|
883
|
+
const auditMode = this.config.auditMode;
|
|
884
|
+
try {
|
|
885
|
+
const originalDescriptor = Object.getOwnPropertyDescriptor(
|
|
886
|
+
process,
|
|
887
|
+
"execPath"
|
|
888
|
+
);
|
|
889
|
+
this.originalDescriptors.push({
|
|
890
|
+
target: process,
|
|
891
|
+
prop: "execPath",
|
|
892
|
+
descriptor: originalDescriptor
|
|
893
|
+
});
|
|
894
|
+
const currentValue = originalDescriptor?.value ?? process.execPath;
|
|
895
|
+
Object.defineProperty(process, "execPath", {
|
|
896
|
+
get() {
|
|
897
|
+
const message = "process.execPath access is blocked in worker context";
|
|
898
|
+
const violation = self.recordViolation(
|
|
899
|
+
"process_exec_path",
|
|
900
|
+
"process.execPath",
|
|
901
|
+
message
|
|
902
|
+
);
|
|
903
|
+
if (!auditMode) {
|
|
904
|
+
throw new WorkerSecurityViolationError(message, violation);
|
|
905
|
+
}
|
|
906
|
+
return currentValue;
|
|
907
|
+
},
|
|
908
|
+
set(value) {
|
|
909
|
+
const message = "process.execPath modification is blocked in worker context";
|
|
910
|
+
const violation = self.recordViolation(
|
|
911
|
+
"process_exec_path",
|
|
912
|
+
"process.execPath",
|
|
913
|
+
message
|
|
914
|
+
);
|
|
915
|
+
if (!auditMode) {
|
|
916
|
+
throw new WorkerSecurityViolationError(message, violation);
|
|
917
|
+
}
|
|
918
|
+
Object.defineProperty(process, "execPath", {
|
|
919
|
+
value,
|
|
920
|
+
writable: true,
|
|
921
|
+
configurable: true
|
|
922
|
+
});
|
|
923
|
+
},
|
|
924
|
+
configurable: true
|
|
925
|
+
});
|
|
926
|
+
} catch {
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
/**
|
|
930
|
+
* Protect process.connected from being read or set in worker context.
|
|
931
|
+
*
|
|
932
|
+
* process.connected is a boolean primitive (not an object), so it cannot be
|
|
933
|
+
* proxied via the normal blocked globals mechanism. We use Object.defineProperty
|
|
934
|
+
* with getter/setter (same pattern as protectProcessExecPath).
|
|
935
|
+
*
|
|
936
|
+
* Only protects if process.connected exists (IPC contexts).
|
|
937
|
+
*/
|
|
938
|
+
protectProcessConnected() {
|
|
939
|
+
if (typeof process === "undefined") return;
|
|
940
|
+
if (process.connected === void 0) return;
|
|
941
|
+
const self = this;
|
|
942
|
+
const auditMode = this.config.auditMode;
|
|
943
|
+
try {
|
|
944
|
+
const originalDescriptor = Object.getOwnPropertyDescriptor(
|
|
945
|
+
process,
|
|
946
|
+
"connected"
|
|
947
|
+
);
|
|
948
|
+
this.originalDescriptors.push({
|
|
949
|
+
target: process,
|
|
950
|
+
prop: "connected",
|
|
951
|
+
descriptor: originalDescriptor
|
|
952
|
+
});
|
|
953
|
+
const currentValue = originalDescriptor?.value ?? process.connected;
|
|
954
|
+
Object.defineProperty(process, "connected", {
|
|
955
|
+
get() {
|
|
956
|
+
const message = "process.connected access is blocked in worker context";
|
|
957
|
+
const violation = self.recordViolation(
|
|
958
|
+
"process_connected",
|
|
959
|
+
"process.connected",
|
|
960
|
+
message
|
|
961
|
+
);
|
|
962
|
+
if (!auditMode) {
|
|
963
|
+
throw new WorkerSecurityViolationError(message, violation);
|
|
964
|
+
}
|
|
965
|
+
return currentValue;
|
|
966
|
+
},
|
|
967
|
+
set(value) {
|
|
968
|
+
const message = "process.connected modification is blocked in worker context";
|
|
969
|
+
const violation = self.recordViolation(
|
|
970
|
+
"process_connected",
|
|
971
|
+
"process.connected",
|
|
972
|
+
message
|
|
973
|
+
);
|
|
974
|
+
if (!auditMode) {
|
|
975
|
+
throw new WorkerSecurityViolationError(message, violation);
|
|
976
|
+
}
|
|
977
|
+
Object.defineProperty(process, "connected", {
|
|
978
|
+
value,
|
|
979
|
+
writable: true,
|
|
980
|
+
configurable: true
|
|
981
|
+
});
|
|
982
|
+
},
|
|
983
|
+
configurable: true
|
|
984
|
+
});
|
|
985
|
+
} catch {
|
|
986
|
+
}
|
|
987
|
+
}
|
|
764
988
|
/**
|
|
765
989
|
* Protect Module._load from being called.
|
|
766
990
|
*
|