mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-08-27 16:02:28 +02:00
fix(c2pa): drop non-printable claim_generator garbage
On some manifests (observed: Microsoft Designer) the first CBOR "name" key precedes a binary hash field, not the generator string, so _cbor_text_after returns control-char garbage. Guard with isprintable() to drop it; issuer detection (byte-search) and the SynthID verdict are unaffected. Adds TestParseChunkGuards covering kept-vs-dropped cases. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
da0edcbddc
commit
6cef1d59f0
@@ -9,6 +9,7 @@ import pytest
|
||||
|
||||
from remove_ai_watermarks.noai.c2pa import (
|
||||
_cbor_text_after,
|
||||
_parse_c2pa_chunk,
|
||||
extract_c2pa_chunk,
|
||||
extract_c2pa_info,
|
||||
has_c2pa_metadata,
|
||||
@@ -232,6 +233,32 @@ class TestSynthIDVerdict:
|
||||
assert "Google LLC, OpenAI" in synthid_verdict("Google LLC, OpenAI")
|
||||
|
||||
|
||||
class TestParseChunkGuards:
|
||||
"""_parse_c2pa_chunk rejects non-printable claim_generator garbage.
|
||||
|
||||
On some manifests (observed: Microsoft Designer) the first ``name`` key
|
||||
precedes a binary hash field, not the generator string. The clean issuer +
|
||||
SynthID verdict must still come through.
|
||||
"""
|
||||
|
||||
def test_clean_generator_kept(self):
|
||||
# "name" + CBOR text-string (head 0x69 = 0x60+9) "gpt-image"
|
||||
chunk = b"...name" + bytes([0x69]) + b"gpt-image" + b"OpenAI trainedAlgorithmicMedia"
|
||||
info: dict = {}
|
||||
_parse_c2pa_chunk(chunk, info)
|
||||
assert info["claim_generator"] == "gpt-image"
|
||||
assert "OpenAI" in info["issuer"]
|
||||
assert "synthid_watermark" in info # OpenAI + trainedAlgorithmicMedia
|
||||
|
||||
def test_nonprintable_generator_dropped(self):
|
||||
# "name" + CBOR string (head 0x64 = len 4) with a control byte -> garbage
|
||||
chunk = b"...name" + bytes([0x64]) + b"\x81abc" + b"OpenAI trainedAlgorithmicMedia"
|
||||
info: dict = {}
|
||||
_parse_c2pa_chunk(chunk, info)
|
||||
assert "claim_generator" not in info # control-char garbage rejected
|
||||
assert "OpenAI" in info["issuer"] # issuer byte-search still robust
|
||||
|
||||
|
||||
# ── ISOBMFF (AVIF / HEIF / JPEG-XL container stripping) ──────────────
|
||||
|
||||
FTYP = b"\x00\x00\x00\x18ftypavif\x00\x00\x00\x00avifmif1" # 24-byte ftyp box
|
||||
|
||||
Reference in New Issue
Block a user