Use RE for proof extraxtion
This commit is contained in:
parent
46cab38b8a
commit
2d4143fde6
1 changed files with 108 additions and 10 deletions
|
|
@ -72,6 +72,11 @@ type FlagMatchRule = {
|
||||||
description: string;
|
description: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type FlagMatchRuleValue = {
|
||||||
|
path: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
|
||||||
type FlagMatchInfo = {
|
type FlagMatchInfo = {
|
||||||
field: string;
|
field: string;
|
||||||
value: string;
|
value: string;
|
||||||
|
|
@ -87,13 +92,35 @@ const ruleScreenshot = (): FlagMatchRule[] => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
field:
|
field:
|
||||||
"integrity/c2pa/manifest_info/manifests[]/assertions[]/{label=c2pa.actions}/data/actions[]/{action=c2pa.created}/digitalSourceType",
|
"integrity/c2pa/manifest_info/manifests[]/assertions[label=c2pa.actions]/data/actions[action=c2pa.created]/digitalSourceType",
|
||||||
match: [C2PASourceTypeScreenCapture],
|
match: [C2PASourceTypeScreenCapture],
|
||||||
description: "Screen capture",
|
description: "Screen capture",
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ruleCamera = (): FlagMatchRule[] => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
field:
|
||||||
|
"integrity/c2pa/manifest_info/manifests[]/assertions[label=c2pa.actions]/data/actions[action=c2pa.created]/digitalSourceType",
|
||||||
|
match: [C2PASourceTypeDigitalCapture, C2PASourceTypeComputationalCapture, C2PASourceTypeCompositeCapture],
|
||||||
|
description: "Captured by camera",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
const ruleAiGenerated = (): FlagMatchRule[] => {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
field:
|
||||||
|
"integrity/c2pa/manifest_info/manifests[]/assertions[label=c2pa.actions]/data/actions[action=c2pa.created]/digitalSourceType",
|
||||||
|
match: [C2PASourceTypeTrainedAlgorithmicMedia, C2PASourceTypeCompositeWithTrainedAlgorithmicMedia],
|
||||||
|
description: "Generated by AI",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
const aiHintFlags = (): FlagMatchRule[] => {
|
const aiHintFlags = (): FlagMatchRule[] => {
|
||||||
const knownAIServices = [
|
const knownAIServices = [
|
||||||
"ChatGPT",
|
"ChatGPT",
|
||||||
|
|
@ -122,13 +149,22 @@ const matchFlag = (rules: FlagMatchRule[], file: any) => {
|
||||||
const matchParts = (parts: string[], o: any, re: RegExp[]): FlagMatch[] | undefined => {
|
const matchParts = (parts: string[], o: any, re: RegExp[]): FlagMatch[] | undefined => {
|
||||||
if (parts.length == 0 || o == undefined) return undefined;
|
if (parts.length == 0 || o == undefined) return undefined;
|
||||||
let part = parts[0];
|
let part = parts[0];
|
||||||
if (part.endsWith("[]")) {
|
const lastBracket = part.lastIndexOf("[");
|
||||||
part = part.substring(0, part.length - 2);
|
if (part.endsWith("]") && lastBracket > 0) {
|
||||||
|
const optionalConstraint = part.substring(lastBracket + 1, part.length - 1);
|
||||||
|
part = part.substring(0, lastBracket);
|
||||||
if (o[part] != undefined) {
|
if (o[part] != undefined) {
|
||||||
let opart: any[] = o[part];
|
let opart: any[] = o[part];
|
||||||
if (!Array.isArray(opart)) {
|
if (!Array.isArray(opart)) {
|
||||||
opart = Object.values(opart) ?? [];
|
opart = Object.values(opart) ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Any constraints controlling what array object(s) to consider?
|
||||||
|
if (optionalConstraint) {
|
||||||
|
const [prop, val] = optionalConstraint.split("=");
|
||||||
|
opart = opart.filter((item) => item[prop] === val);
|
||||||
|
}
|
||||||
|
|
||||||
if (parts.length == 1) {
|
if (parts.length == 1) {
|
||||||
let strings = opart as string[];
|
let strings = opart as string[];
|
||||||
if (!strings) return undefined;
|
if (!strings) return undefined;
|
||||||
|
|
@ -156,13 +192,6 @@ const matchFlag = (rules: FlagMatchRule[], file: any) => {
|
||||||
} else {
|
} else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
} else if (part.startsWith("{") && part.endsWith("}")) {
|
|
||||||
const [prop, val] = part.substring(1, part.length - 1).split("=");
|
|
||||||
if (o[prop] === val) {
|
|
||||||
return matchParts(parts.slice(1), o, re);
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (o[part] != undefined) {
|
if (o[part] != undefined) {
|
||||||
if (parts.length == 1) {
|
if (parts.length == 1) {
|
||||||
|
|
@ -203,6 +232,71 @@ const matchFlag = (rules: FlagMatchRule[], file: any) => {
|
||||||
return { result: result, matches: resultInfo };
|
return { result: result, matches: resultInfo };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const extractFlagValues = (flagPath: string, file: any): FlagMatchRuleValue[] => {
|
||||||
|
const getValues = (path: string[], objectPath: any[], actualPath: string, o: any): FlagMatchRuleValue[] | undefined => {
|
||||||
|
if (path.length == 0 || o == undefined) return undefined;
|
||||||
|
let part = path[0];
|
||||||
|
const lastBracket = part.lastIndexOf("[");
|
||||||
|
if (part === "..") {
|
||||||
|
return getValues(path.slice(1), objectPath.slice(1), actualPath + "/..", objectPath[0]);
|
||||||
|
}
|
||||||
|
if (part.endsWith("]") && lastBracket > 0) {
|
||||||
|
const optionalConstraint = part.substring(lastBracket + 1, part.length - 1);
|
||||||
|
part = part.substring(0, lastBracket);
|
||||||
|
if (o[part] != undefined) {
|
||||||
|
let opart: any[] = o[part];
|
||||||
|
if (!Array.isArray(opart)) {
|
||||||
|
opart = Object.values(opart) ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any constraints controlling what array object(s) to consider?
|
||||||
|
if (optionalConstraint) {
|
||||||
|
const [prop, val] = optionalConstraint.split("=");
|
||||||
|
opart = opart.filter((item) => item[prop] === val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path.length == 1) {
|
||||||
|
let strings = opart as string[];
|
||||||
|
return strings.map((s, i) => ({ path: actualPath + "/" + part + "[" + i + "]", value: s }));
|
||||||
|
} else {
|
||||||
|
return opart.reduce((res: FlagMatchRuleValue[] | undefined, o: any, i: number) => {
|
||||||
|
const newObjectPaths = [o, ...objectPath];
|
||||||
|
let matches = getValues(path.slice(1), newObjectPaths, actualPath + "/" + part + "[" + i + "]", o);
|
||||||
|
if (matches) {
|
||||||
|
const r2 = res || [];
|
||||||
|
r2.push(...matches);
|
||||||
|
return r2;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}, undefined);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (o[part] != undefined) {
|
||||||
|
if (path.length == 1) {
|
||||||
|
return [{ path: actualPath + "/" + part, value: o[part] }];
|
||||||
|
} else {
|
||||||
|
const newObjectPaths = [o, ...objectPath];
|
||||||
|
return getValues(path.slice(1), newObjectPaths, actualPath + "/" + part, o[part]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let result: FlagMatchRuleValue[] = [];
|
||||||
|
try {
|
||||||
|
let parts = flagPath.split("/");
|
||||||
|
result = getValues(parts, [], "", file) ?? [];
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Invalid RE", e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
export const extractProofHintFlags = (proof?: Proof): ProofHintFlags | undefined => {
|
export const extractProofHintFlags = (proof?: Proof): ProofHintFlags | undefined => {
|
||||||
if (!proof) return undefined;
|
if (!proof) return undefined;
|
||||||
|
|
||||||
|
|
@ -258,6 +352,10 @@ export const extractProofHintFlags = (proof?: Proof): ProofHintFlags | undefined
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (valid) {
|
if (valid) {
|
||||||
|
|
||||||
|
const dateCreated = extractFlagValues("integrity/c2pa/manifest_info/manifests[]/assertions[label=c2pa.actions]/data/actions[action=c2pa.created]/../../../../signature_info/issuer", proof);
|
||||||
|
console.error("DATE CREATED", dateCreated);
|
||||||
|
|
||||||
screenshot = matchFlag(ruleScreenshot(), proof).result;
|
screenshot = matchFlag(ruleScreenshot(), proof).result;
|
||||||
const flags: ProofHintFlags = {
|
const flags: ProofHintFlags = {
|
||||||
aiGenerated,
|
aiGenerated,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue