UNPKG

greed.js

Version:

Run Python libraries in the browser with WebGPU acceleration - PyTorch, NumPy, and more. Modular architecture with full backward compatibility.

1 lines 17.6 kB
"use strict";(this.webpackChunkGreed=this.webpackChunkGreed||[]).push([[738],{219:(e,t,i)=>{i.d(t,{A:()=>n});var s=i(123);class r extends s.A{constructor(e={}){super(),this.config={strictMode:!1!==e.strictMode,allowEval:!0===e.allowEval,allowFileSystem:!0===e.allowFileSystem,allowNetwork:!0===e.allowNetwork,allowSubprocess:!0===e.allowSubprocess,maxCodeLength:e.maxCodeLength||1e5,maxTensorSize:e.maxTensorSize||1e8,maxTensorCount:e.maxTensorCount||100,maxStringLength:e.maxStringLength||1e4,maxMemoryMB:e.maxMemoryMB||1024,maxExecutionTimeMs:e.maxExecutionTimeMs||3e4,allowedPackages:new Set(e.allowedPackages||["numpy","math","random","json","datetime","collections","itertools","functools","operator","re"]),customDangerousPatterns:e.customDangerousPatterns||[],customAllowedPatterns:e.customAllowedPatterns||[],...e},this.dangerousPatterns=this._initializeDangerousPatterns(),this.suspiciousPatterns=this._initializeSuspiciousPatterns(),this.fileSystemPatterns=this._initializeFileSystemPatterns(),this.networkPatterns=this._initializeNetworkPatterns(),this.stats={totalValidations:0,blockedOperations:0,warningsIssued:0,lastValidation:null,threatCategories:{}}}validatePythonCode(e,t={}){const i=performance.now();this.stats.totalValidations++;try{this.emit("validation:start",{codeLength:e.length,strict:this.config.strictMode}),this._validateCodeInput(e);const s=this._analyzeSecurityThreats(e),r=this._assessRiskLevel(s),o=this._enforceSecurityPolicy(e,s,r,t);this._updateValidationStats(s,r,o);const n=performance.now()-i;return this.emit("validation:complete",{threats:s.length,riskLevel:r,allowed:o.allowed,validationTime:n}),o}catch(t){throw this.emit("validation:error",{error:t,codePreview:e.substring(0,100)}),t}}validateTensorData(e,t={}){const i=Array.isArray(e)?e:[e];this.emit("tensor:validation:start",{tensorCount:i.length});try{if(i.length>this.config.maxTensorCount)throw new o(`Too many tensors: ${i.length} > ${this.config.maxTensorCount}`);let e=0,t=0;for(let s=0;s<i.length;s++){const r=i[s];if(!this._isValidTensorType(r))throw new o(`Invalid tensor type at index ${s}: ${typeof r}`);const n=this._getTensorElementCount(r);if(n>this.config.maxTensorSize)throw new o(`Tensor too large at index ${s}: ${n} > ${this.config.maxTensorSize}`);const a=this._estimateTensorMemoryMB(r);t+=a,e+=n,this.emit("tensor:validated",{index:s,elements:n,memoryMB:Math.round(100*a)/100})}if(t>this.config.maxMemoryMB)throw new o(`Total tensor memory too large: ${Math.round(t)}MB > ${this.config.maxMemoryMB}MB`);return this.emit("tensor:validation:complete",{tensorCount:i.length,totalElements:e,totalMemoryMB:Math.round(100*t)/100}),{valid:!0,tensorCount:i.length,totalElements:e,totalMemoryMB:t,warnings:[]}}catch(e){throw this.emit("tensor:validation:error",{error:e}),e}}validateOperation(e,t,i={}){this.emit("operation:validation:start",{operation:e});try{if(!e||"string"!=typeof e)throw new o("Operation must be a non-empty string");if(e.length>100)throw new o(`Operation name too long: ${e.length} > 100`);if(["eval","exec","compile","__import__","subprocess"].some(t=>e.toLowerCase().includes(t)))throw new o(`Dangerous operation detected: ${e}`);const s=this._validateOperationParams(t),r=this._validateOperationOptions(i);return this.emit("operation:validation:complete",{operation:e,paramCount:Object.keys(s).length}),{valid:!0,operation:e,params:s,options:r}}catch(t){throw this.emit("operation:validation:error",{operation:e,error:t}),t}}validateURL(e,t={}){const{allowedDomains:i=[],blockedDomains:s=[],requireHTTPS:r=!0}=t;try{const t=new URL(e);if(r&&"https:"!==t.protocol)throw new o(`HTTPS required for URL: ${e}`);if(s.includes(t.hostname))throw new o(`Blocked domain: ${t.hostname}`);if(i.length>0&&!i.includes(t.hostname))throw new o(`Domain not in allowlist: ${t.hostname}`);if([/localhost/i,/127\.0\.0\.1/,/0\.0\.0\.0/,/\[::\]/,/internal/i,/private/i,/admin/i,/\.local$/i].some(t=>t.test(e)))throw new o(`Suspicious URL pattern detected: ${e}`);return{valid:!0,url:t.href,domain:t.hostname}}catch(t){if(t instanceof o)throw t;throw new o(`Invalid URL: ${e} - ${t.message}`)}}getStats(){return{...this.stats,config:{strictMode:this.config.strictMode,maxTensorSize:this.config.maxTensorSize,maxMemoryMB:this.config.maxMemoryMB,allowedPackages:Array.from(this.config.allowedPackages)}}}updateConfig(e){const t={...this.config};this.config={...this.config,...e},e.allowedPackages&&(this.config.allowedPackages=new Set(e.allowedPackages)),this.emit("config:updated",{oldConfig:t,newConfig:this.config})}resetStats(){this.stats={totalValidations:0,blockedOperations:0,warningsIssued:0,lastValidation:null,threatCategories:{}},this.emit("stats:reset")}_validateCodeInput(e){if("string"!=typeof e)throw new o("Code must be a string");if(0===e.length)throw new o("Code cannot be empty");if(e.length>this.config.maxCodeLength)throw new o(`Code too long: ${e.length} > ${this.config.maxCodeLength}`);if(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/.test(e))throw new o("Code contains invalid control characters")}_analyzeSecurityThreats(e){const t=[];for(const[i,s]of Object.entries(this.dangerousPatterns))for(const r of s){const s=e.match(r.regex);s&&t.push({category:i,type:"dangerous",pattern:r.name,severity:r.severity,matches:s.length,description:r.description,firstMatch:s[0]})}for(const[i,s]of Object.entries(this.suspiciousPatterns))for(const r of s){const s=e.match(r.regex);s&&t.push({category:i,type:"suspicious",pattern:r.name,severity:r.severity,matches:s.length,description:r.description,firstMatch:s[0]})}if(!this.config.allowFileSystem)for(const i of this.fileSystemPatterns){const s=e.match(i.regex);s&&t.push({category:"filesystem",type:"blocked",pattern:i.name,severity:"high",matches:s.length,description:"File system access not allowed",firstMatch:s[0]})}if(!this.config.allowNetwork)for(const i of this.networkPatterns){const s=e.match(i.regex);s&&t.push({category:"network",type:"blocked",pattern:i.name,severity:"high",matches:s.length,description:"Network access not allowed",firstMatch:s[0]})}return t}_assessRiskLevel(e){if(0===e.length)return"low";const t=e.filter(e=>"critical"===e.severity).length,i=e.filter(e=>"high"===e.severity).length,s=e.filter(e=>"medium"===e.severity).length;return t>0||i>2?"critical":i>0||s>3?"high":s>0?"medium":"low"}_enforceSecurityPolicy(e,t,i,s={}){const{allowWarnings:r=!1,bypassValidation:n=!1}=s;if(n&&!this.config.strictMode)return this.emit("policy:bypassed",{riskLevel:i,threats:t.length}),{allowed:!0,bypassed:!0,riskLevel:i,threats:t,warnings:["Security validation was bypassed"]};if("critical"===i||"high"===i&&this.config.strictMode)throw this.stats.blockedOperations++,this.emit("policy:blocked",{riskLevel:i,threats:t.length}),new o(`Security policy violation: ${i} risk detected with ${t.length} threats`);if("medium"===i){if(r)return this.stats.warningsIssued++,this.emit("policy:warning",{riskLevel:i,threats:t.length}),{allowed:!0,riskLevel:i,threats:t,warnings:t.map(e=>`${e.category}: ${e.description}`)};if(this.config.strictMode)throw this.stats.blockedOperations++,new o(`Security policy violation: ${i} risk detected (strict mode)`)}return{allowed:!0,riskLevel:i,threats:t,warnings:"low"===i?[]:t.map(e=>`${e.category}: ${e.description}`)}}_isValidTensorType(e){return ArrayBuffer.isView(e)||e instanceof ArrayBuffer||Array.isArray(e)||e&&"object"==typeof e&&e.constructor&&e.constructor.name.includes("Array")}_getTensorElementCount(e){return ArrayBuffer.isView(e)?e.length:e instanceof ArrayBuffer?e.byteLength/4:Array.isArray(e)?e.length:0}_estimateTensorMemoryMB(e){return this._getTensorElementCount(e)*(ArrayBuffer.isView(e)?e.BYTES_PER_ELEMENT:4)/1048576}_validateOperationParams(e){const t={};for(const[i,s]of Object.entries(e||{})){if("string"!=typeof i||i.length>100)throw new o(`Invalid parameter key: ${i}`);if("string"==typeof s&&s.length>this.config.maxStringLength)throw new o(`Parameter value too long: ${i}`);t[i]=s}return t}_validateOperationOptions(e){const t={},i=["timeout","strategy","workgroupSize","dataType","precision","optimization","caching","parallel"];for(const[s,r]of Object.entries(e||{}))i.includes(s)?t[s]=r:this.emit("option:unknown",{key:s,value:r});return t}_updateValidationStats(e,t,i){this.stats.lastValidation={timestamp:Date.now(),threats:e.length,riskLevel:t,allowed:i.allowed};for(const t of e)this.stats.threatCategories[t.category]||(this.stats.threatCategories[t.category]=0),this.stats.threatCategories[t.category]++}_initializeDangerousPatterns(){return{codeExecution:[{name:"eval",regex:/\beval\s*\(/g,severity:"critical",description:"Dynamic code execution with eval()"},{name:"exec",regex:/\bexec\s*\(/g,severity:"critical",description:"Dynamic code execution with exec()"},{name:"compile",regex:/\bcompile\s*\(/g,severity:"high",description:"Code compilation detected"}],imports:[{name:"dynamic_import",regex:/\b__import__\s*\(/g,severity:"high",description:"Dynamic import detected"},{name:"importlib",regex:/\bimportlib\./g,severity:"medium",description:"Import library usage"}],subprocess:[{name:"subprocess",regex:/\bsubprocess\./g,severity:"critical",description:"Subprocess execution"},{name:"os_system",regex:/\bos\.system\s*\(/g,severity:"critical",description:"OS system command execution"},{name:"popen",regex:/\bos\.popen\s*\(/g,severity:"critical",description:"Process execution with popen"}]}}_initializeSuspiciousPatterns(){return{reflection:[{name:"getattr",regex:/\bgetattr\s*\(/g,severity:"medium",description:"Attribute access via getattr"},{name:"setattr",regex:/\bsetattr\s*\(/g,severity:"medium",description:"Attribute modification via setattr"},{name:"hasattr",regex:/\bhasattr\s*\(/g,severity:"low",description:"Attribute existence check"}],globals:[{name:"globals",regex:/\bglobals\s*\(\s*\)/g,severity:"medium",description:"Access to global namespace"},{name:"locals",regex:/\blocals\s*\(\s*\)/g,severity:"medium",description:"Access to local namespace"},{name:"vars",regex:/\bvars\s*\(/g,severity:"low",description:"Variable inspection"}]}}_initializeFileSystemPatterns(){return[{name:"open",regex:/\bopen\s*\(/g,severity:"high",description:"File opening operation"},{name:"file",regex:/\bfile\s*\(/g,severity:"high",description:"File object creation"},{name:"pathlib",regex:/\bpathlib\./g,severity:"medium",description:"Path manipulation"}]}_initializeNetworkPatterns(){return[{name:"urllib",regex:/\burllib\./g,severity:"high",description:"URL library usage"},{name:"requests",regex:/\brequests\./g,severity:"high",description:"HTTP requests library"},{name:"socket",regex:/\bsocket\./g,severity:"high",description:"Socket networking"}]}}class o extends Error{constructor(e,t="security",i="high"){super(e),this.name="SecurityError",this.category=t,this.severity=i,this.timestamp=(new Date).toISOString()}}const n=r},626:(e,t,i)=>{i.d(t,{A:()=>r});class s{constructor(e={}){this.config={level:e.level||"warn",enableConsole:!1!==e.enableConsole,prefix:e.prefix||"Greed",timestamp:!1!==e.timestamp,...e},this.levels={error:0,warn:1,info:2,debug:3},this.currentLevelPriority=this.levels[this.config.level]||1}_shouldLog(e){return this.levels[e]<=this.currentLevelPriority}_formatMessage(e,t,...i){return{formatted:`${[this.config.timestamp?(new Date).toISOString():"",this.config.prefix?`[${this.config.prefix}]`:"",`[${e.toUpperCase()}]`].filter(Boolean).join(" ")} ${t}`,args:i}}error(e,...t){if(this._shouldLog("error")&&this.config.enableConsole){const{formatted:i,args:s}=this._formatMessage("error",e,...t);console.error(i,...s)}}warn(e,...t){if(this._shouldLog("warn")&&this.config.enableConsole){const{formatted:i,args:s}=this._formatMessage("warn",e,...t);console.warn(i,...s)}}info(e,...t){if(this._shouldLog("info")&&this.config.enableConsole){const{formatted:i,args:s}=this._formatMessage("info",e,...t);console.log(i,...s)}}debug(e,...t){if(this._shouldLog("debug")&&this.config.enableConsole){const{formatted:i,args:s}=this._formatMessage("debug",e,...t);console.log(i,...s)}}setLevel(e){e in this.levels&&(this.config.level=e,this.currentLevelPriority=this.levels[e])}child(e){return new s({...this.config,prefix:`${this.config.prefix}:${e}`})}}const r=new s},683:(e,t,i)=>{i.d(t,{A:()=>n});var s=i(123),r=i(626);class o extends s.A{constructor(e={}){super(),this.config={maxMemoryMB:e.maxMemoryMB||1024,gcThreshold:e.gcThreshold||.8,checkInterval:e.checkInterval||5e3,enableAutoGC:!1!==e.enableAutoGC,...e},this.resources=new Map,this.bufferPool=new Map,this.activeBuffers=new Set,this.memoryUsage=0,this.peakMemoryUsage=0,this.gcCount=0,this.registry=null,this.cleanupTasks=new Set,this.monitoringInterval=null,this._initializeFinalizationRegistry(),this.config.enableAutoGC&&this._startMemoryMonitoring()}register(e,t,i={}){const{size:s=0,type:r="generic",priority:o="normal",autoRelease:n=!0}=i,a=this._generateId(),c={id:a,resource:e,cleanup:t,size:s,type:r,priority:o,autoRelease:n,createdAt:Date.now(),lastAccessed:Date.now()};return this.resources.set(a,c),this.memoryUsage+=s,this.peakMemoryUsage=Math.max(this.peakMemoryUsage,this.memoryUsage),this.registry&&n&&this.registry.register(e,{id:a,cleanup:t},e),this.emit("resource:registered",{id:a,type:r,size:s}),this._shouldRunGC()&&this._scheduleGC(),a}async unregister(e){const t=this.resources.get(e);if(!t)return!1;try{return await this._cleanupResource(t),this.resources.delete(e),this.memoryUsage-=t.size,this.emit("resource:unregistered",{id:e,type:t.type,size:t.size}),!0}catch(t){return this.emit("cleanup:error",{id:e,error:t}),!1}}allocateBuffer(e,t,i=GPUBufferUsage.STORAGE|GPUBufferUsage.COPY_SRC|GPUBufferUsage.COPY_DST){const s=`${t}-${i}`,r=this.bufferPool.get(s);let o;r&&r.length>0?(o=r.pop(),this.emit("buffer:reused",{size:t,usage:i})):(o=e.createBuffer({size:t,usage:i}),this.emit("buffer:created",{size:t,usage:i})),this.activeBuffers.add(o);const n=this.register(o,()=>this._cleanupBuffer(o),{size:t,type:"webgpu-buffer",priority:"high"});return o._greedId=n,o}releaseBuffer(e,t={}){const{destroy:i=!1,poolMaxSize:s=20}=t;if(!this.activeBuffers.has(e))return!1;if(this.activeBuffers.delete(e),e._greedId&&this.unregister(e._greedId),i)return e.destroy(),this.emit("buffer:destroyed",{buffer:e}),!0;const r=`${e.size}-${e.usage}`;this.bufferPool.has(r)||this.bufferPool.set(r,[]);const o=this.bufferPool.get(r);return o.length<s?(o.push(e),this.emit("buffer:pooled",{buffer:e,poolSize:o.length})):(e.destroy(),this.emit("buffer:destroyed",{buffer:e,reason:"pool-full"})),!0}async forceGC(e={}){const{aggressive:t=!1,targetReduction:i=.3,maxAge:s=3e5}=e;this.gcCount++;const r=performance.now(),o=this.memoryUsage;this.emit("gc:start",{aggressive:t,targetReduction:i});try{let e=0;const n=Date.now(),a=Array.from(this.resources.entries()).sort(([,e],[,t])=>{if(e.priority!==t.priority){const i={low:0,normal:1,high:2};return i[e.priority]-i[t.priority]}return n-e.lastAccessed-(n-t.lastAccessed)});for(const[r,c]of a){const a=n-c.lastAccessed;if((t||a>s||"low"===c.priority&&this._shouldRunGC())&&c.autoRelease&&await this.unregister(r)&&e++,(o-this.memoryUsage)/o>=i)break}window.gc&&t&&window.gc();const c=performance.now()-r,l=o-this.memoryUsage;return this.emit("gc:complete",{cleaned:e,duration:c,memoryReduction:l,newMemoryUsage:this.memoryUsage}),{cleaned:e,memoryReduction:l,duration:c}}catch(e){throw this.emit("gc:error",{error:e}),e}}getStats(){return{memoryUsage:this.memoryUsage,memoryUsageMB:Math.round(this.memoryUsage/1048576*100)/100,maxMemoryMB:this.config.maxMemoryMB,peakMemoryUsage:this.peakMemoryUsage,peakMemoryUsageMB:Math.round(this.peakMemoryUsage/1048576*100)/100,memoryUtilization:this.memoryUsage/(1024*this.config.maxMemoryMB*1024),resourceCount:this.resources.size,activeBuffers:this.activeBuffers.size,bufferPools:this.bufferPool.size,gcCount:this.gcCount,resourceTypes:this._getResourceTypeStats()}}async cleanup(){this.emit("cleanup:start");try{this.monitoringInterval&&(clearInterval(this.monitoringInterval),this.monitoringInterval=null);const e=Array.from(this.resources.keys());for(const t of e)await this.unregister(t);for(const e of this.bufferPool.values())for(const t of e)t.destroy();this.bufferPool.clear();for(const e of this.activeBuffers)e.destroy();this.activeBuffers.clear(),this.memoryUsage=0,this.emit("cleanup:complete")}catch(e){throw this.emit("cleanup:error",{error:e}),e}}_initializeFinalizationRegistry(){"undefined"!=typeof FinalizationRegistry&&(this.registry=new FinalizationRegistry(({id:e,cleanup:t})=>{try{if(t(),this.resources.has(e)){const t=this.resources.get(e);this.resources.delete(e),this.memoryUsage-=t.size,this.emit("resource:finalized",{id:e})}}catch(t){this.emit("finalization:error",{id:e,error:t})}}))}_startMemoryMonitoring(){this.monitoringInterval=setInterval(()=>{this._shouldRunGC()&&this.forceGC({aggressive:!1})},this.config.checkInterval)}_shouldRunGC(){const e=1024*this.config.maxMemoryMB*1024;return this.memoryUsage>e*this.config.gcThreshold}_scheduleGC(){setTimeout(()=>this.forceGC(),0)}async _cleanupResource(e){try{"function"==typeof e.cleanup&&await e.cleanup()}catch(t){throw new Error(`Failed to cleanup resource ${e.id}: ${t.message}`)}}_cleanupBuffer(e){return new Promise(t=>{try{e&&"function"==typeof e.destroy&&e.destroy(),t()}catch(i){r.A.warn("Buffer cleanup error:",{bufferId:e._greedId,error:i.message,stack:i.stack}),t()}})}_generateId(){return`mem_${Date.now()}_${Math.random().toString(36).substr(2,9)}`}_getResourceTypeStats(){const e={};for(const t of this.resources.values())e[t.type]||(e[t.type]={count:0,totalSize:0}),e[t.type].count++,e[t.type].totalSize+=t.size;return e}}const n=o}}]);