diff --git a/src/models/proof.ts b/src/models/proof.ts index ff0d0c9..4081c4c 100644 --- a/src/models/proof.ts +++ b/src/models/proof.ts @@ -148,6 +148,7 @@ const pathsC2PACreationDate = (): FlagValue[] => { const pathsC2PACamera = (): FlagValue[] => { return [ + {path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data{exif:SceneType=1|directly photographed image}"}, {path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:LensMake"}, {path: "integrity/c2pa/manifest_info/manifests[]/assertions[label=stds.exif]/data/exif:LensModel"}, ]; @@ -155,6 +156,7 @@ const pathsC2PACamera = (): FlagValue[] => { const pathsExifCamera = (): FlagValue[] => { return [ + {path: "integrity/exif{SceneType=1|directly photographed image}"}, {path: "integrity/exif/LensMake"}, {path: "integrity/exif/LensModel"}, ]; @@ -263,69 +265,76 @@ const extractFlagValues = (flagPath: string, path: FlagMatchRulePathSegment[]): path: FlagMatchRulePathSegment[] ): FlagMatchRuleValue[] | undefined => { if (keys.length == 0 || path.length == 0) return undefined; - + const o = path[0].object; let key = keys[0]; - const lastBracket = key.lastIndexOf("["); if (key === "..") { return getValues(keys.slice(1), path.slice(1)); } - if (key.endsWith("]") && lastBracket > 0) { - const optionalConstraint = key.substring(lastBracket + 1, key.length - 1); + + const lastBracket = key.lastIndexOf("["); + const hasBracket = key.endsWith("]") && lastBracket > 0; + const lastBrace = key.lastIndexOf("{"); + const hasBrace = key.endsWith("}") && lastBrace > 0; + + let optionalConstraint: String | undefined = undefined; + + if (hasBracket) { + optionalConstraint = key.substring(lastBracket + 1, key.length - 1); key = key.substring(0, lastBracket); - if (o[key] != undefined) { - let opart: any[] = o[key]; - if (!Array.isArray(opart)) { - opart = Object.values(opart) ?? []; - } + } else if (hasBrace) { + optionalConstraint = key.substring(lastBrace + 1, key.length - 1); + key = key.substring(0, lastBrace); + } - // Any constraints controlling what array object(s) to consider? - if (optionalConstraint) { - if (optionalConstraint.startsWith("!!")) { - // Ignore this path in the tree if ANY of the values contain the constraint match. - const [prop, val] = optionalConstraint.substring(2).split("="); - if (opart.some((item) => item[prop] === val)) { - return undefined; - } - } else if (optionalConstraint.startsWith("!")) { - const [prop, val] = optionalConstraint.substring(1).split("="); - opart = opart.filter((item) => item[prop] !== val); - } else { - const [prop, val] = optionalConstraint.split("="); - let valarray = val.split("|"); - opart = opart.filter((item) => valarray.includes(item[prop])); - } - } + let nextObject = o[key]; + let omatches: any[] = nextObject ? (Array.isArray(nextObject) ? nextObject : hasBracket ? Object.values(nextObject) : [nextObject]) : []; - if (keys.length == 1) { - return opart.map((s, i) => { - return { value: o, path: [{ object: s, path: key + "[" + i + "]"}, ... path] }; - }); - } else { - return opart.reduce((res: FlagMatchRuleValue[] | undefined, oin: any, i: number) => { - let matches = getValues(keys.slice(1), [ { object: oin, path: key + "[" + i + "]"}, ... path]); - if (matches) { - const r2 = res || []; - r2.push(...matches); - return r2; - } - return res; - }, undefined); + // Any constraints controlling what array object(s) to consider? + if (optionalConstraint) { + if (optionalConstraint.startsWith("!!")) { + // Ignore this path in the tree if ANY of the values contain the constraint match. + const [prop, val] = optionalConstraint.substring(2).split("="); + let valarray = val.split("|"); + if (omatches.some((item) => valarray.includes(item[prop]))) { + omatches = []; } + } else if (optionalConstraint.startsWith("!")) { + const [prop, val] = optionalConstraint.substring(1).split("="); + let valarray = val.split("|"); + omatches = omatches.filter((m) => { + return valarray.includes(m[prop]); + }); } else { - return undefined; + const [prop, val] = optionalConstraint.split("="); + let valarray = val.split("|"); + omatches = omatches.filter((m) => { + return valarray.includes(m[prop]); + }); + } + } + + if (omatches.length > 0) { + if (keys.length == 1) { + return omatches.map((oin, i) => { + return { value: oin, path: [{ object: oin, path: key + (omatches.length > 1 ? `[${i}]` : "") }, ...path] }; + }); + } else if (omatches.length == 1) { + return getValues(keys.slice(1), [{object: omatches[0], path: key}, ...path]); + } else { + return omatches.reduce((res: FlagMatchRuleValue[] | undefined, oin: any, i: number) => { + let matches = getValues(keys.slice(1), [{ object: oin, path: key + "[" + i + "]" }, ...path]); + if (matches) { + const r2 = res || []; + r2.push(...matches); + return r2; + } + return res; + }, undefined); } } else { - if (o[key] != undefined) { - if (keys.length == 1) { - return [{ value: o[key], path: [{object: o[key], path: key}, ...path] }]; - } else { - return getValues(keys.slice(1), [{object: o[key], path: key}, ...path]); - } - } else { - return undefined; - } + return undefined; } };