tricu

A lazy functional language based on Tree Calculus
Log | Files | Refs | README | LICENSE

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 }