runtime-fixtures.mjs (4489B)
1 // Constructor-only security fixtures, independent of the compiler/evaluator. 2 import {makeBundle} from './bundle-fixture.mjs'; 3 import {createHash} from 'node:crypto'; 4 export function fixtures(){ 5 const result={}; 6 const fixture=(name,build)=>{ 7 const nodes=[],memo=new Map(); 8 const node=(...children)=>{const key=children.join(',');if(memo.has(key))return memo.get(key);const id=nodes.length;nodes.push(children);memo.set(key,id);return id;}; 9 const leaf=node(),fork=(a,b)=>node(a,b),num=n=>n===0?leaf:fork(n%2?node(leaf):leaf,num(Math.floor(n/2))); 10 const list=xs=>xs.reduceRight((tail,x)=>fork(x,tail),leaf),text=s=>list(Array.from(s,c=>num(c.codePointAt(0)))); 11 const action=(tag,payload)=>fork(num(tag),payload),constant=t=>fork(leaf,t); 12 const io=(value,version=1)=>fork(text('tricuIO'),fork(num(version),value)); 13 const root=build({leaf,stem:a=>node(a),fork,num,text,action,constant,io});const bytes=makeBundle(nodes,[['root',root]]); 14 result[name]={bytes:[...bytes],hash:createHash('sha256').update(bytes).digest('hex')}; 15 }; 16 fixture('pure-number',x=>x.num(42)); 17 fixture('v1-output',x=>x.io(x.action(10,x.text('v1 output')))); 18 fixture('padded-v1',x=>x.fork(x.text('tricuIO'),x.fork(x.fork(x.stem(x.leaf),x.fork(x.leaf,x.leaf)),x.action(10,x.text('MUST NOT WRITE'))))); 19 fixture('unknown-version',x=>x.io(x.action(10,x.text('MUST NOT WRITE')),3)); 20 fixture('version',x=>x.io(x.action(0,x.leaf),2)); 21 fixture('version-effect',x=>x.io(x.action(10,x.text('MUST NOT WRITE')),2)); 22 fixture('unsupported',x=>x.io(x.action(99,x.leaf))); 23 fixture('abort',x=>{let t=x.leaf;for(let i=0;i<40;i++)t=x.fork(t,t);return x.io(x.action(2,t));}); 24 fixture('output',x=>{let a=x.action(0,x.leaf);const write=x.action(10,x.text('x'.repeat(4096)));for(let i=0;i<5;i++)a=x.action(1,x.fork(write,x.constant(a)));return x.io(a);}); 25 fixture('actions',x=>{let a=x.action(0,x.leaf);for(let i=0;i<65;i++)a=x.action(1,x.fork(x.action(0,x.leaf),x.constant(a)));return x.io(a);}); 26 fixture('sharing',x=>{let t=x.leaf;for(let i=0;i<40;i++)t=x.fork(t,t);return t;}); 27 for(let code=0;code<10;code++)fixture('v2-header-core-'+code,x=>{let payload=x.leaf;for(let i=0;i<80;i++)payload=x.fork(payload,payload);return x.action(code,payload);}); 28 const req=(x,g,v,op)=>x.action(10,x.fork(g,x.fork(v,x.fork(op,x.leaf)))); 29 fixture('v2-header-future',x=>req(x,x.text('future-9'),x.num(65535),x.text('unknown'))); 30 fixture('v2-header-long-name',x=>req(x,x.text('a'.repeat(64)),x.num(1),x.text('read'))); 31 fixture('v2-header-bad-tag',x=>x.fork(x.fork(x.leaf,x.leaf),x.leaf)); 32 fixture('v2-header-bad-name',x=>req(x,x.text('a'.repeat(65)),x.num(1),x.text('read'))); 33 fixture('v2-header-bad-revision',x=>req(x,x.text('file'),x.num(65536),x.text('read'))); 34 fixture('v2-header-zero-revision',x=>req(x,x.text('file'),x.num(0),x.text('read'))); 35 fixture('v2-header-bad-shape',x=>x.leaf); 36 const seq=(x,a,b)=>x.action(1,x.fork(a,x.constant(b))); 37 fixture('v2-run-pure',x=>x.action(0,x.num(42))); 38 fixture('v2-run-bind',x=>seq(x,x.action(0,x.num(7)),x.action(0,x.num(42)))); 39 fixture('v2-run-scope',x=>x.action(3,x.constant(seq(x,x.action(4,x.leaf),x.action(0,x.num(42)))))); 40 for(const supervised of [0,1])fixture('v2-run-child-'+supervised,x=>{ 41 const child=x.action(2,x.num(7)); 42 const spawn=x.action(5,x.fork(x.num(supervised),x.fork(x.num(0),x.fork(x.leaf,x.constant(child))))); 43 return seq(x,spawn,x.action(0,x.num(42))); 44 }); 45 fixture('v2-run-unsupported',x=>seq(x,req(x,x.text('future'),x.num(1),x.text('read')),x.action(0,x.num(42)))); 46 fixture('v2-run-discard-invalid',x=>seq(x,x.action(7,x.leaf),x.action(0,x.num(42)))); 47 for(const tag of [2,9])fixture('v2-run-terminal-'+tag,x=>{let opaque=x.leaf;for(let i=0;i<80;i++)opaque=x.fork(opaque,opaque);return x.action(tag,opaque);}); 48 fixture('v2-run-malformed',x=>x.action(1,x.leaf)); 49 fixture('v2-session-streams',x=>{ 50 const marker=(name,key)=>x.fork(x.text(name),x.fork(x.num(1),x.fork(x.num(key),x.leaf))); 51 const request=(group,op,args)=>x.action(10,x.fork(x.text(group),x.fork(x.num(1),x.fork(x.text(op),args)))); 52 const read=request('stream','read',x.fork(marker('io.v2.resource',1),x.num(8))); 53 const write=request('stream','write',x.fork(marker('io.v2.resource',2),x.fork(x.num(65),x.leaf))); 54 const spawn=x.action(5,x.fork(x.num(1),x.fork(x.num(0),x.fork(x.leaf,x.constant(read))))); 55 const cancel=x.action(8,x.fork(marker('io.v2.task',1),x.leaf)); 56 return seq(x,spawn,seq(x,write,seq(x,cancel,x.action(0,x.num(42))))); 57 }); 58 return result; 59 }