Revert "Reuse immutable JSON validation proofs without weakening publication checks"
This reverts commit 697716ee89.
This commit is contained in:
@@ -46,38 +46,10 @@ export function readSet<T>(input: Iterable<T>): ReadonlyValueSet<T> {
|
||||
};
|
||||
return Object.freeze(view);
|
||||
}
|
||||
// Successful proofs only: frozen data properties whose children have their own
|
||||
// immutable proof. Neither shallow freeze nor a user-defined Array.every qualifies.
|
||||
const jsonHeights=new WeakMap<object,number>(),nativeEvery=Array.prototype.every;
|
||||
function jsonShape(value:object,array:boolean,every:unknown){
|
||||
try{const own=array?Object.getOwnPropertyDescriptor(value,'every'):undefined;return Array.prototype.every===nativeEvery&&(!array||Object.getPrototypeOf(value)===Array.prototype&&!!own&&Object.hasOwn(own,'value')&&own.value===nativeEvery&&every===nativeEvery);}
|
||||
catch{return false;}
|
||||
}
|
||||
function jsonHeight(value:unknown):number|undefined{
|
||||
if(value===null||typeof value==='string'||typeof value==='boolean'||typeof value==='number'&&Number.isFinite(value))return 0;
|
||||
return value&&typeof value==='object'?jsonHeights.get(value):undefined;
|
||||
}
|
||||
export function validJson(value: unknown, depth = 0): value is Json {
|
||||
if (depth > 64) return false;
|
||||
if (value === null || typeof value === 'string' || typeof value === 'boolean') return true;
|
||||
if (typeof value === 'number') return Number.isFinite(value);
|
||||
if(!value||typeof value!=='object')return false;
|
||||
const array=Array.isArray(value);
|
||||
if(!array&&Object.getPrototypeOf(value)!==Object.prototype)return false;
|
||||
const every=array?value.every:undefined,ordinary=jsonShape(value,array,every);
|
||||
const proven=ordinary?jsonHeights.get(value):undefined;
|
||||
if(proven!==undefined)return !(depth+proven>64);
|
||||
const valid=array?Reflect.apply(every!,value,[(item:unknown)=>validJson(item,depth+1)]):Object.values(value).every(child=>validJson(child,depth+1));
|
||||
if(valid&&ordinary)try{if(Object.isFrozen(value)){
|
||||
let height=0,immutable=true;
|
||||
const keys=array?undefined:Object.keys(value);
|
||||
for(let index=0;index<(array?value.length:keys!.length);index++){
|
||||
const key=array?String(index):keys![index];
|
||||
const descriptor=Object.getOwnPropertyDescriptor(value,key),child=descriptor&&Object.hasOwn(descriptor,'value')?jsonHeight(descriptor.value):undefined;
|
||||
if(child===undefined){immutable=false;break;}
|
||||
height=Math.max(height,child+1);
|
||||
}
|
||||
if(immutable)jsonHeights.set(value,height);
|
||||
}}catch{/* Optional proof inspection cannot reject an otherwise valid value. */}
|
||||
return valid;
|
||||
if (Array.isArray(value)) return value.every(item => validJson(item, depth + 1));
|
||||
return !!value && typeof value === 'object' && Object.getPrototypeOf(value) === Object.prototype && Object.values(value).every(child => validJson(child, depth + 1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user