Pro edycjastabilność: Eksperymentalna
Podgląd C2PA — szczegółowa dokumentacja referencyjna
W skrócie
Dział zatytułowany „W skrócie”Ta strona jest dokumentacją na poziomie kontraktu dla powierzchni podglądu C2PA (Content Credentials) w NextPDF Pro. Obejmuje pięć publicznych symboli w NextPDF\Pro\Compliance\C2pa: SPI C2paManifestEmbedder, obiekt wartości ManifestStore, JumbfBoxParser, deskryptor C2paCapabilityStatus oraz bramkowany Experimental\ExperimentalC2paEmbedder. Dokumentuje także bramkę Feature::PREVIEW_C2PA_DRAFT i jej zmienną środowiskową NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT.
Powierzchnia jest eksperymentalna i podzielona na dwie warstwy. Stabilna złączka — ManifestStore, C2paManifestEmbedder, JumbfBoxParser — jest zawsze osiągalna i przenosi bajty Manifest Store w obie strony. Synteza roboczego manifestu istnieje wyłącznie w ExperimentalC2paEmbedder i jest domyślnie wyłączona. Profil C2PA-PDF nie został sfinalizowany przez grupę roboczą; syntezowany format transmisji jest przypięty do roboczego commitu. Nie deklaruje się żadnej zgodności, nie istnieje ścieżka weryfikacji, a włączenie flagi podglądu nie może stworzyć żadnej z nich. Widok zorientowany na zadania znajduje się na stronie możliwości.
Dostępność i licencjonowanie
Dział zatytułowany „Dostępność i licencjonowanie”Ta możliwość jest dostarczana w NextPDF Pro (nextpdf/pro) i aktywuje się wraz z kopertą licencyjną poziomu Pro. Wdrożenie bez tego uprawnienia nie ładuje klas tej możliwości. Porównaj edycje i uzyskaj licencję.
Licencja aktywuje całą powierzchnię zgodności Pro. Powierzchnia C2PA wewnątrz niej pozostaje podglądem niezależnie od poziomu licencji. Synteza wersji roboczej dodatkowo wymaga bramki procesu opisanej tutaj; sama licencja Pro nigdy jej nie włącza.
Publiczna powierzchnia API
Dział zatytułowany „Publiczna powierzchnia API”| Symbol | Parametry | Zachowanie domyślne | Zwraca | Zgłasza lub kończy się niepowodzeniem z | Uwagi |
|---|---|---|---|---|---|
C2paManifestEmbedder | — | Wyłącznie bajtowe SPI osadzania/wyodrębniania; brak I/O; brak syntezy deklaracji | — | — | Zamrożony, neutralny wobec dostawcy interfejs złączki. |
C2paManifestEmbedder::embed() | string $pdfBytes, ManifestStore $store | Osadza $store->toBytes() w miejscu zadeklarowanym w profilu; pusty Store MOŻE przejść tam i z powrotem jako no-op | string nowe bajty PDF | C2paException przy dowolnym niepowodzeniu osadzania (nadmiarowy Store, nieprawidłowy PDF, kolizja lokalizacji profilu) | Implementacje nigdy nie modyfikują ani nie zatrzymują wejściowych bajtów. |
C2paManifestEmbedder::extract() | string $pdfBytes | Tania sonda wykrywająca; przypadek braku Store alokuje niemal nic | ?ManifestStore (null przy braku) | Podklasa C2paException, gdy Store jest obecny, ale narusza niezmiennik utwardzenia | Niepusty Store przeszedł już utwardzenie JumbfBoxParser. |
ManifestStore::fromBoxes() | array $boxes (list<JumbfBox>) | Opakowuje uporządkowaną listę pól zwalidowaną przez parser | self | Sam nie zgłasza; ręczna konstrukcja JumbfBox wymusza to samo utwardzenie | Konstruktor jest prywatny; kolejność pól ma znaczenie dla równości przy przejściu tam i z powrotem. |
ManifestStore::empty() | brak | Store z zerową liczbą pól głównych | self | Nie zgłasza | toBytes() pustego Store to pusty ciąg znaków. |
ManifestStore::isEmpty() | brak | Sprawdza brak pól głównych | bool | Nie zgłasza | — |
ManifestStore::toBytes() | brak | Łączy serializacje pól głównych | string | Nie zgłasza | Ta sekwencja bajtów jest tym, co zapisuje mechanizm osadzający. |
ManifestStore::size() | brak | Długość w bajtach toBytes() | int (>= 0) | Nie zgłasza | — |
JumbfBoxParser::__construct() | trzy opcjonalne nadpisania limitów | Limity produkcyjne: 64 MiB na pole, 128 MiB łącznie, 4096 elementów potomnych na superpole | JumbfBoxParser | Nie zgłasza | Limit głębokości jest ustalony na MAX_DEPTH (8) i nie jest konfigurowalny przez konstruktor. |
JumbfBoxParser::parse() | string $bytes | Waliduje i materializuje pola główne; puste wejście daje [] | list<JumbfBox> | JumbfBombException, JumbfCycleDetectedException, JumbfDepthExceededException, MalformedJumbfException | Bezstanowy; nigdy nie zwraca częściowego grafu; równoczesne wywołania na jednej instancji są bezpieczne. |
C2paCapabilityStatus::__construct() | sześć nazwanych pól readonly | Buduje dowolną instancję deskryptora | C2paCapabilityStatus | Nie zgłasza | current() jest kanonicznym konstruktorem. |
C2paCapabilityStatus::current() | brak | Odczytuje bramkę na żywo; ustawia wartości logiczne deklaracji na stałe | C2paCapabilityStatus | Nie zgłasza | generallyAvailable i conformanceClaimed są zawsze false. |
C2paCapabilityStatus::summary() | brak | Jednowierszowy tekst statusu | string | Nie zgłasza | Sformułowany tak, by nie zawierać deklaracji GA ani zgodności. |
Feature | enum oparty na string, 1 przypadek | Pojedynczy przypadek PREVIEW_C2PA_DRAFT; stała ENV_PREVIEW_C2PA_DRAFT | przypadek enum | Nic przy dostępie do przypadku | Zakresowa bramka stabilności; odrębna od uprawnienia licencyjnego. |
Feature::isEnabled() | brak | Odczytuje getenv() na żywo; ścisłe porównanie z ciągiem 1 | bool | Nie zgłasza | Brak zmiennej lub dowolna inna wartość, w tym 0, true, yes, oznacza wyłączenie. |
ExperimentalC2paEmbedder::__construct() | brak | Kontrola bramki fail-closed w czasie konstrukcji | ExperimentalC2paEmbedder | LogicException, gdy Feature::PREVIEW_C2PA_DRAFT jest wyłączona | Nie istnieje żaden cichy mechanizm awaryjny. |
ExperimentalC2paEmbedder::buildManifestStore() | string $sourceBytes, string $producer (niepusty) | Buduje Store o kształcie roboczym wiążący $sourceBytes przez SHA-256 | ManifestStore | \JsonException przy niepowodzeniu kodowania ładunku; podklasy C2paException z konstrukcji pól | Pomija pole c2cs Claim Signature; wyjście jest z założenia niepodpisane. |
interface C2paManifestEmbedder
public function embed(string $pdfBytes, ManifestStore $store): string;public function extract(string $pdfBytes): ?ManifestStore;final readonly class ManifestStore
public static function fromBoxes(array $boxes): selfpublic static function empty(): selfpublic function isEmpty(): boolpublic function toBytes(): stringpublic function size(): intfinal class JumbfBoxParser
public const int MAX_DEPTH = 8;public const int MAX_PER_BOX_BYTES = 64 * 1024 * 1024;public const int MAX_TOTAL_BYTES = 128 * 1024 * 1024;public const int MAX_CHILDREN_PER_SUPERBOX = 4096;public const array SUPERBOX_TBOXES = ['jumb', 'c2pa', 'c2ma', 'c2as', 'c2cl', 'c2cs', 'c2vc'];
public function __construct( private readonly int $maxPerBoxBytes = self::MAX_PER_BOX_BYTES, private readonly int $maxTotalBytes = self::MAX_TOTAL_BYTES, private readonly int $maxChildrenPerSuperbox = self::MAX_CHILDREN_PER_SUPERBOX,)
public function parse(string $bytes): arrayfinal readonly class C2paCapabilityStatus
public const string MATURITY_PREVIEW_DRAFT = 'preview-draft';
public function __construct( public bool $previewEnabled, public bool $generallyAvailable, public bool $conformanceClaimed, public string $maturity, public string $specPin, public string $envGate,)
public static function current(): selfpublic function summary(): stringenum Feature: string
case PREVIEW_C2PA_DRAFT = 'preview_c2pa_draft';
public const string ENV_PREVIEW_C2PA_DRAFT = 'NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT';
public function isEnabled(): boolfinal class ExperimentalC2paEmbedder
public const string SPEC_PIN_SHA = '4e2afed8f3ace20d41317e2e386c9340d2959d55';public const string SPEC_PIN_DATE = '2026-04-26';
public function __construct()
public function buildManifestStore(string $sourceBytes, string $producer): ManifestStoreKontrakt zachowania
Dział zatytułowany „Kontrakt zachowania”- Podział dwuwarstwowy. Stabilna złączka (
ManifestStore,C2paManifestEmbedder,JumbfBoxParser) jest zawsze osiągalna. Synteza wersji roboczej istnieje wyłącznie wNextPDF\Pro\Compliance\C2pa\Experimental\ExperimentalC2paEmbedderza domyślnie wyłączoną bramką. Wyodrębnianie i przenoszenie bajtów nigdy nie wymaga bramki; synteza wymaga jej zawsze. - Niezmienniki złączki. Kontrakt
C2paManifestEmbedderjest wyłącznie bajtowy: przez złączkę nie przechodzą żadne obiekty PDF w pamięci, implementacje nie wykonują I/O sieciowego ani plikowego, a złączka nigdy sama nie składa asercji deklaracji.extract()zwracanull, aby zasygnalizować brak; nigdy nie zgłasza wyjątku z powodu braku. - Semantyka Store.
ManifestStorejest niezmienną, uporządkowaną listą głównych instancjiJumbfBox, zgodnie z modelem Manifest Store z C2PA 2.1 §11.1.1: jeden kontener JUMBF agregujący jeden lub więcej manifestów, adresowalny przez URI. Nie udostępnia żadnych akcesorów na poziomie deklaracji. Kolejność pól jest zachowywana i ma znaczenie dla równości przy przejściu tam i z powrotem. - Limity utwardzenia.
JumbfBoxParserbezwarunkowo odrzuca wejścia przekraczające dowolny limit: rozmiar pojedynczego pola powyżej 64 MiB, skumulowany store powyżej 128 MiB, zagnieżdżenie głębsze niż 8 poziomów lub więcej niż 4096 elementów potomnych w jednym superpolu. Żadna flaga polityki nie wyłącza tych limitów. Ściślejsze limity można wstrzyknąć przez konstruktor dla procesów o ograniczonej pamięci. - Odrzucenie strukturalne. Parser odrzuca również, fail-closed:
LBox = 0(BMFF do EOF),LBox = 1(XLBox 64-bitowa długość),LBoxmniejszy niż 8-bajtowy nagłówek, obcięcie poza pozostałym wejściem, bajty TBox spoza drukowalnego ASCII (0x20–0x7E), ponowne wejście po offsecie (cykle) oraz niedokładne kafelkowanie potomków w ładunku superpola. Nigdy nie zwraca częściowo skonstruowanego grafu. - Routing superpól. Wartości TBox w
SUPERBOX_TBOXESsą parsowane rekurencyjnie jako sekwencje potomków; każdy inny TBox jest liściem z nieprzejrzystym ładunkiem.cborjest celowo traktowany jako liść ze względu na bezpieczeństwo parsera; warstwy nadrzędne ponownie parsują jego ładunek, gdy jest to potrzebne. - Bramka procesu.
Feature::PREVIEW_C2PA_DRAFTjest domyślnie wyłączona.isEnabled()zwracatruetylko wtedy, gdyNEXTPDF_FEATURE_PREVIEW_C2PA_DRAFTjest dokładnie równe ciągowi1. Odczyt jest na żywo przy każdym wywołaniu; nic nie jest zapamiętywane. - Konstrukcja fail-closed.
new ExperimentalC2paEmbedder()zgłaszaLogicException, gdy bramka jest wyłączona. Komunikat wymienia flagę, zmienną środowiskową oraz przypięty roboczy SHA i datę. Wywołujący nie może przypadkowo dotrzeć do syntezy wersji roboczej. - Kształt syntezy.
buildManifestStore()emituje superpolec2pazawierające jeden manifestc2ma, który przechowuje magazyn asercjic2as(jedna asercjac2pa.hash.data) oraz deklaracjęc2cl. Asercja zapisuje asercję skrótu SHA-256 nad$sourceBytes; ponieważ polec2csClaim Signature jest pominięte, a wyjście jest niepodpisane, NIE jest to twarde wiązanie (hard binding) C2PA ani werdykt o proweniencji — podąża jedynie za kształtem strukturalnym opisanym w §9.1. Ładunki pól Description niosą UUID typu, przełączniki0x03oraz zakończoną znakiem null etykietę UTF-8, zgodnie z C2PA 2.1 §11.1.4.1.1–11.1.4.1.2. - Brak Claim Signature. Pole
c2cs— zgodnie z C2PA 2.1 §11.1.4.4 pojedyncze pole zawartości CBOR z etykietąc2pa.signature— jest celowo pomijane w syntezowanym Store. Wyjście jest z założenia niepodpisane. To obszar profilu oceniony jako najbardziej prawdopodobny do zmiany przed zamrożeniem przez grupę roboczą. - Przypięcie wersji roboczej, brak gwarancji BC. Syntezowany format transmisji jest przypięty do
SPEC_PIN_SHA(4e2afed8…, z datą2026-04-26) repozytoriumc2pa-org/specifications. Może się zmienić bez powiadomienia i nie niesie żadnej gwarancji wstecznej kompatybilności. - Niezmiennik uczciwości.
C2paCapabilityStatus::current()ustawia na stałegenerallyAvailableiconformanceClaimednafalse. Żadna konfiguracja ani flaga środowiskowa nie przełącza żadnej z tych wartości logicznych. TylkopreviewEnabledodzwierciedla bramkę;maturityjest niedeklarującym tokenempreview-draft.
Przypadki brzegowe i tryby awarii
Dział zatytułowany „Przypadki brzegowe i tryby awarii”- Ustawienie zmiennej bramki na
0,true,yes,onlub pusty ciąg pozostawia bramkę wyłączoną. Tylko dokładny ciąg1ją włącza. - Zmiany
putenv()wchodzą w życie przy następnym wywołaniuisEnabled(), ponieważ odczyt jest na żywo. Bramka przełączona w trakcie procesu jest obserwowana natychmiast. extract()rozróżnia dwa wyniki:null, gdy nie ma żadnego Store (tanie, bez wyjątków), oraz zgłoszoną podklasęC2paException, gdy Store jest obecny, ale wrogi lub zniekształcony. Brak nigdy nie jest błędem; obecność wraz ze zniekształceniem zawsze nim jest.JumbfBoxParser::parse('')zwraca pustą listę. Pusty, lecz obecnyManifestStoreprzechodzi tam i z powrotem do samego siebie; złączka nie zwija go donull.- Osadzenie pustego Store MOŻE zwrócić wejście bez zmian. Kontrakt złączki dopuszcza ten no-op, lecz go nie nakazuje.
- Ręcznie zbudowane grafy
JumbfBoxprzechodzą to samo utwardzenie w czasie konstrukcji: kontrole długości i ASCII TBox, limit głębokości, niezmiennik głębokości potomków, regułę wyłączności ładunek-lub-potomkowie oraz limit rozmiaru pojedynczego pola. Ręcznie zbudowana bomba kończy się niepowodzeniem przy konstrukcji, a nie przy osadzaniu. - Każdy wyjątek parsera niesie ustrukturyzowane pola —
capKind/observed/cap,offsetlubkind— dzięki czemu telemetria nie zeskrobuje ciągów komunikatów. Wszystkie podklasy rozszerzająC2paException(samą będącąRuntimeException), która jest parasolowym typem przechwytywania. - Docblock parsera zakazuje cichego połykania tych wyjątków; konsumenci wynoszą je na powierzchnię lub przemapowują je z intencją.
buildManifestStore()koduje ładunki JSON zJSON_THROW_ON_ERROR; ciąg$producer, który nie jest prawidłowym UTF-8, kończy się niepowodzeniem z\JsonException, zanim zbudowane zostanie jakiekolwiek pole.- Poprawnie sformułowany wynik
extract()jest wyłącznie stwierdzeniem strukturalnym. Nigdzie na tej powierzchni nie ma walidacji deklaracji, weryfikacji podpisu ani oceny zaufania. Rozpoznanie nie jest werdyktem o proweniencji. - Ta powierzchnia nie przetwarza żadnego klucza podpisu, certyfikatu ani struktury COSE. Jedyną operacją kryptograficzną jest skrót zawartości SHA-256 wewnątrz bramkowanej ścieżki syntezy.
Zgodność
Dział zatytułowany „Zgodność”| Deklaracja | Standard | Klauzula |
|---|---|---|
| Manifesty serializują się do jednego store JUMBF przechowującego wiele manifestów, adresowalnych przez URI. | C2PA 2.1 | §11.1.1 (p63.b) |
| Etykiety pól Description są zakończonym znakiem null UTF-8 z wykluczonymi zakresami; przełączniki są zdefiniowane dla wszystkich pól Description. | C2PA 2.1 | §11.1.4.1.1–11.1.4.1.2 (p63.a) |
Pole Claim Signature ma etykietę c2pa.signature, typ c2cs i przechowuje pojedyncze pole zawartości CBOR. | C2PA 2.1 | §11.1.4.4 (p63.c) |
| Twarde wiązanie kryptograficznie łączy manifest z jego zasobem i ujawnia modyfikację — niepodpisana asercja skrótu w podglądzie NIE spełnia tego progu. | C2PA 2.1 | §9.1 (p57) |
Wszystkie klauzule są parafrazowane. NextPDF nie odtwarza tekstu normatywnego. NextPDF nie posiada żadnej certyfikacji i żadnej nie udziela. Powyższe stwierdzenia są stwierdzeniami o zgodności strukturalnej dotyczącymi układu pól, etykiet i wiązań — nie są wynikami testów zgodności, nie są atestacjami stron trzecich ani deklaracją zgodności z C2PA czy ISO. Profil C2PA-PDF nie jest sfinalizowany; syntezowany format transmisji śledzi przypięty roboczy commit. C2paCapabilityStatus koduje tę postawę w kodzie: generallyAvailable i conformanceClaimed są false w każdej konfiguracji. Wyjście z tej powierzchni nie jest weryfikowalnym Content Credential, a w NextPDF nie istnieje żadna ścieżka weryfikacji.
Uwagi deweloperskie
Dział zatytułowany „Uwagi deweloperskie”-
Gramatyka pól JUMBF, którą implementuje parser (4-bajtowy big-endian LBox, 4-bajtowy ASCII TBox, ładunek; superpola zagnieżdżają pola potomne), podąża za ISO 19566-5; standard ten jest poza cytowanym korpusem, więc zachowanie parsera jest oparte na źródle produktu, a nie na cytacie ze specyfikacji.
-
Utrzymuj bramkę wyłączoną w produkcji. Synteza wersji roboczej nie dodaje trwałej możliwości; emitowane bajty są przejściowe i powinny zostać ponownie osadzone, gdy tylko pojawi się stabilny adapter.
-
Weryfikuj
ExperimentalC2paEmbedder::SPEC_PIN_SHAwzględem roboczego commitu, którego oczekuje Twój potok. Uruchomcomposer c2pa:draft-statusw CI (kod wyjścia 0 świeży, 1 miękkie ostrzeżenie, 2 twarda porażka), aby wykryć nieaktualność przypięcia. -
Traktuj
C2paCapabilityStatus::current()jako jedyne źródło prawdy przy prezentowaniu statusu C2PA w narzędziach lub UI. Nie powtarzaj jego wartości logicznych ręcznie;summary()jest bezpieczne dla logów i punktów końcowych statusu. -
Przechwytuj
C2paExceptionjako typ parasolowy podczas konsumowaniaextract()lubparse(). Mapuj cztery podklasy na odrębne liczniki telemetrii, używając ich ustrukturyzowanych pól. -
Wstrzyknij ściślejsze limity przez konstruktor
JumbfBoxParserdla procesów weryfikatora o ograniczonej pamięci; wartości domyślne są hojnymi limitami produkcyjnymi. -
C2paCapabilityStatus::__construct()jest publiczny, więc ręcznie zbudowana instancja może nieść dowolne wartości logiczne. Taka instancja jest jedynie obiektem wartości; nie zmienia żadnego zachowania.
Zobacz także
Dział zatytułowany „Zobacz także”- Status możliwości podglądu C2PA — strona możliwości
- Bezpieczeństwo — dokumentacja szczegółowa (Pro)
- Zgodność — dokumentacja szczegółowa (Pro)
- Podgląd podpisywania post-kwantowego — dokumentacja szczegółowa (Enterprise)
- Bezpieczeństwo / Podpisywanie (Core)
Granica publikacji
Dział zatytułowany „Granica publikacji”Ta strona dokumentuje wyłącznie zewnętrznie obserwowalne zachowanie oraz wspieraną publiczną powierzchnię API. Wewnętrzne ścieżki przestrzeni nazw, klasy pomocnicze, tabele mechanizmów, nazwy plików runbooków oraz prefiksy zgłoszeń są poza zakresem.