Dokument PDF, ki prispe na proizvodno mejo — v tiskalno vrsto, arhiv, portal za nalaganje s strani strank — je treba pred kakršnim koli upodabljanjem pregledati. Datoteka morda vsebuje dejanje »Zagon« (Launch), ki je usmerjeno na zagon zunanjega programa, morda vsebuje preveč grobe slike, da bi tisk preživele, morda prinaša šifrirni slovar, ki prepoveduje natanko tisti tiskalni posel, za katerega je bil dokument predložen, ali pa nosi oznako za standard PDF/A, čeprav mu sploh ne ustreza. Pregledovanje dokumenta na podlagi takšnih pravil, še preden vstopi v sam delovni tok, se imenuje preflight, orodje in API PDFium v jeziku C (PDFium C API) pa daje Delphiju vse, kar je potrebno za neposredno izvedbo pregledov, ne da bi mu bilo treba upodobiti eno samo stran
Ta članek zgradi dejanska preverjanja (checks): štiri revizijske razrede, od katerih je vsak manjša rutina, ki na skupni seznam rezultatov doda svoje ugotovitve (findings). Interaktivni elementi, metrika virov, varnostno stanje in oznake standardov dobijo polno delujočo kodo, vključno z aritmetiko in matematiko. Če potrebujete mehanizem okoli teh preverjanj — zanke za serijsko obdelavo map (batch folder loops), json v poročilih ter formatiranje poročil JSON in HTML, ali pa osamitev za vsako datoteko posebej (per-file isolation) — komponenta PDFium vključuje že pripravljen preflight mehanizem in članek o batch preflight CLI pokriva tudi to ogrodje. Oba namenoma delita enoten besednjak izhodnih kod (exit-code vocabulary), tako da se tukaj napisani revizor neposredno prilega gonilniku tiste serijske obdelave (batch driver)
Zapis o ugotovitvi in pogodba o izhodni kodi (exit-code contract)
Vsako preverjanje piše rezultate v enotno plosko strukturo zapisa (flat record type), ker se alternative, kjer bi vsak pregled natisnil svoje besedilo, ne bi dalo prešteti, filtrirati ali določiti pragov napak za kasneje. Štirje razdelki oziroma polja so dovolj:
uses
System.SysUtils, System.Math, System.IOUtils,
System.Generics.Collections, pdfium_lib;
type
TFindingSeverity = (fsInfo, fsWarning, fsError);
TPreflightFinding = record
Severity: TFindingSeverity;
Code: string; // stable machine key, e.g. 'ACT-LAUNCH'
Page: Integer; // 1-based; 0 means document level
Message: string; // for humans; free to reword between releases
end;
TFindings = TList<TPreflightFinding>;
procedure Add(Findings: TFindings; Severity: TFindingSeverity;
const Code: string; Page: Integer; const Msg: string);
var
F: TPreflightFinding;
begin
F.Severity := Severity;
F.Code := Code;
F.Page := Page;
F.Message := Msg;
Findings.Add(F);
end;
Orodja obdelave (downstream tooling) temeljijo na polju Code, nikoli na besedilu v Message, katerega se lahko prosto spremeni. Koda za konec procesa (process exit code) sledi enaki pogodbi s tremi vrednostmi, kot je opisano v batch članku: 0 pomeni, da datoteka ni povzročila nobenih ugotovitev, 1 pomeni, da ugotovitve obstajajo, in 2 pomeni, da sama revizija ni mogla biti izvedena, ker datoteke ni bilo mogoče razčleniti ali zahteva geslo. Ločevanje kode 2 je pomembno. Mapa poškodovanih skeniranih dokumentov je posledica pokvarjenega optičnega bralnika navzgor po toku (upstream), ne nenadnega upada ravni skladnosti s pravili, in združitev teh dveh kod bi nekoga poslala v lov za povsem napačnim problemom
Interaktivni elementi: skripti, zagon (launch), zunanje povezave
PDFium razvrsti vsako dejanje, ki ga najde, po celoštevilskem (integer) tipu, in konstante iz datoteke fpdf_doc.h je vredno natančno opredeliti, ker napačno prepisane vrednosti naredijo optični bralnik ali pregledovalnik (scanner) potiho povsem slepega. Dejansko oštevilčevanje (enumeration) je PDFACTION_UNSUPPORTED = 0, PDFACTION_GOTO = 1, PDFACTION_REMOTEGOTO = 2, PDFACTION_URI = 3, PDFACTION_LAUNCH = 4 in PDFACTION_EMBEDDEDGOTO = 5. Upoštevajte tisto, česar tukaj ni (what is absent): ni nobenega člana za JavaScript. Skripti na ravni dokumenta (Document-level scripts) niso dejanja povezav in se nikoli ne pokažejo preko FPDFAction_GetType; našteti in oštevilčeni so z ločeno družino klicev. Revizor, ki testira vrste dejanj proti neki namišljeni (imagined) konstanti JavaScript, se sicer uspešno prevede, zažene (runs), a nikoli in za vedno ne najde ničesar
const
PDFACTION_GOTO = 1; // in-document jump: harmless
PDFACTION_REMOTEGOTO = 2; // jump into another local file
PDFACTION_URI = 3; // opens an external URL
PDFACTION_LAUNCH = 4; // starts an external program
PDFACTION_EMBEDDEDGOTO = 5; // jump into an embedded file
function ActionTarget(Doc: FPDF_DOCUMENT; Action: FPDF_ACTION;
AType: ULONG): string;
var
Buf: array[0..2047] of AnsiChar;
begin
FillChar(Buf, SizeOf(Buf), 0);
if AType = PDFACTION_URI then
FPDFAction_GetURIPath(Doc, Action, @Buf, SizeOf(Buf))
else
FPDFAction_GetFilePath(Action, @Buf, SizeOf(Buf));
Result := string(UTF8String(PAnsiChar(@Buf)));
end;
procedure AuditPageActions(Doc: FPDF_DOCUMENT; Page: FPDF_PAGE;
PageNo: Integer; Findings: TFindings);
var
StartPos: Integer;
Link: FPDF_LINK;
Action: FPDF_ACTION;
AType: ULONG;
begin
StartPos := 0;
while FPDFLink_Enumerate(Page, @StartPos, @Link) <> 0 do
begin
Action := FPDFLink_GetAction(Link);
if Action = nil then
Continue; // destination-only link, nothing to flag
AType := FPDFAction_GetType(Action);
case AType of
PDFACTION_LAUNCH:
Add(Findings, fsError, 'ACT-LAUNCH', PageNo,
'Launch action targets "' + ActionTarget(Doc, Action, AType) + '"');
PDFACTION_URI:
Add(Findings, fsWarning, 'ACT-URI', PageNo,
'link opens ' + ActionTarget(Doc, Action, AType));
PDFACTION_REMOTEGOTO, PDFACTION_EMBEDDEDGOTO:
Add(Findings, fsWarning, 'ACT-XFILE', PageNo,
'cross-file destination "' + ActionTarget(Doc, Action, AType) + '"');
end; // PDFACTION_GOTO stays silent by design
end;
end;
procedure AuditDocumentBehaviors(Doc: FPDF_DOCUMENT; Findings: TFindings);
var
N: Integer;
begin
N := FPDFDoc_GetJavaScriptActionCount(Doc);
if N > 0 then
Add(Findings, fsError, 'JS-DOC', 0,
Format('%d document-level JavaScript action(s) run on open', [N]));
N := FPDFDoc_GetAttachmentCount(Doc);
if N > 0 then
Add(Findings, fsWarning, 'ATT-EMB', 0,
Format('%d embedded file attachment(s)', [N]));
end;
Razdelitev resnosti določa pravilnik (policy). Dejanje za Zagon (Launch action) predstavlja napako, saj je zagon poljubnega zunanjega programa najbolj nevarna stvar, ki jo je mogoče sprožiti s klikom v datoteki PDF, noben zvesti račun pa tega sploh ne potrebuje. Zunanji URI-ji (External URIs) prinašajo opozorila: v povsem legitimnih dokumentih so zelo pogosti, vendar mora in lahko tisti, ki pregled izvaja (reviewer), videti ciljno tarčo tudi brez klikanja na povezavo, saj vidno besedilo tiste povezave in dejanska usmeritev (destination) ni nujno, da se povsem in popolnoma strinjata (need not agree). Skoki tipa GoTo (pojdi na) znotraj samega dokumenta sodijo v in predstavljajo strukturo (structure) ter niso dejanje ali obnašanje (behavior), zato iz samega poročila ostanejo povsem izpuščeni (stay out of the report entirely) — orodje oziroma postopek preflight, ki stalno pošilja oziroma zaganja lažne preplahe ali opozorila (cries wolf) za prav vsak navadni vnos in kazalo vsebine, ljudi priuči zgolj in samo, da to naposled ignorirajo. Za branje celotnega telesa skriptov (script bodies) za preštevanjem JavaScripta ter za zaznavanje ravni MDP podpisov in XFA, članek o nadzoru in reviziji varnostnega tveganja pokriva enako področje s pomočjo objektnega ovoja komponente (component's object wrapper)
Metrika virov: efektivni DPI slike
Slika znotraj dokumenta PDF sploh nima svojega DPI. Vsebuje zgolj in samo piksle (pixels), stran pa postavi te zadevne piksle (pixels) znotraj oziroma v pravokotnik, merjen v točkah (measured in points), kjer 72 točk naredi en inč. Ločljivost ali resolucija (Resolution) obstaja samo kot razmerje the obeh (ratio of the two), kar je razlog, zakaj je ista fotografija 600 krat 400 ostro definirana (razor sharp) kot sličica (thumbnail) in zamegljena zmeda (blurry mess) kot slika v polni velikosti. Revizija zatorej potrebuje obe številki za vsako sliko (both numbers for every image): dimenzije v izvornih pikslih (source pixel dimensions) iz metapodatkov slike, in postavljeni pravokotnik iz meja objekta (object bounds)
procedure AuditPageImages(Page: FPDF_PAGE; PageNo: Integer;
Findings: TFindings);
var
I, ObjCount: Integer;
Obj: FPDF_PAGEOBJECT;
Meta: FPDF_IMAGEOBJ_METADATA;
L, B, R, T: Single;
WidthPt, HeightPt, DpiX, DpiY, EffDpi: Double;
begin
ObjCount := FPDFPage_CountObjects(Page);
for I := 0 to ObjCount - 1 do
begin
Obj := FPDFPage_GetObject(Page, I);
if FPDFPageObj_GetType(Obj) <> FPDF_PAGEOBJ_IMAGE then
Continue;
if FPDFImageObj_GetImageMetadata(Obj, Page, @Meta) = 0 then
Continue;
if FPDFPageObj_GetBounds(Obj, @L, @B, @R, @T) = 0 then
Continue;
WidthPt := R - L; // placed size on the page, in points
HeightPt := T - B;
if (WidthPt <= 0) or (HeightPt <= 0) or
(Meta.Width = 0) or (Meta.Height = 0) then
Continue;
// 72 points = 1 inch, so placed inches = points / 72, and
// effective DPI = source pixels / placed inches.
DpiX := Meta.Width / (WidthPt / 72.0);
DpiY := Meta.Height / (HeightPt / 72.0);
EffDpi := Min(DpiX, DpiY); // the worse axis decides print quality
if EffDpi < 150.0 then
Add(Findings, fsWarning, 'IMG-LOWRES', PageNo,
Format('image %dx%d px placed at %.1fx%.1f pt = %.0f DPI effective',
[Meta.Width, Meta.Height, WidthPt, HeightPt, EffDpi]))
else if EffDpi > 600.0 then
Add(Findings, fsInfo, 'IMG-BLOAT', PageNo,
Format('image is %.0f DPI at placed size; resampling would ' +
'shrink the file with no visible loss', [EffDpi]));
end;
end;
Pragovi (thresholds) so stvar politike (policy), ne fizike: 150 DPI je meja, pod katero pisarniški tisk vidno pikselira, 300 je običajni komercialni cilj, in vse nad 600 ne prinese nobene vidne kakovosti, ampak samo poveča velikost datoteke, kar je razlog, zakaj to raje poroča kot informativno napihnjenost (informational bloat) namesto okvare. Eno pošteno opozorilo (honest caveat): FPDFPageObj_GetBounds vrne škatlo, poravnano z osmi, tako da za sliko, ki je postavljena z rotacijo (rotation), izračunana slika podcenjuje pravo gostoto. Struktura FPDF_IMAGEOBJ_METADATA prav tako vsebuje polja horizontal_dpi in vertical_dpi, ki jih PDFium izpelje iz celotne matrike za transformacijo, in primerjava teh dveh rezultatov je zelo poceni in hiter način za zaznavanje postavljenih rotacij. Ista matematika in aritmetika točk in pikslov omogoča tudi rendering oziroma izrisovanje v obratni smeri, kar je pokrito v članku o JPEG izvozu
Varnostno stanje: šifriranje in biti dovoljenj (permission bits)
Šifriranje v orodju PDF določa dve gesli (two passwords) z različnimi nalogami. Uporabniško geslo (user password) odpira in kontrolira (gates) dešifriranje (decryption): brez njega se datoteka sploh ne odpre, in FPDF_LoadDocument vrne rezultat nil skupaj z napako FPDF_ERR_PASSWORD, ki jo poroča klic FPDF_GetLastError. Lastniško geslo (owner password) na drugi strani določa in kontrolira samo dovoljenja (permissions): datoteka, ki je zaščitena in zavarovana samo in zgolj z lastniškim geslom, se lahko odpre brez akreditivov ali poverilnic (credentials), vendar še vedno prenaša bite omejitev (restriction bits), ki jih mora ustrezen in skladen bralnik (conforming reader) tudi dejansko spoštovati (honor). Poskus nalaganja je zato in zaradi samega sebe hkrati na prvi ravni tudi prva varnostna poizvedba oziroma sonda (first security probe), razlikovanje pa dejansko odloča o izhodni kodi — datoteke, zaklenjene z uporabniškim geslom, preprosto sploh ni mogoče revidirati (koda 2), medtem ko pa lahko datoteko z lastniškim geslom rutinsko preverjamo in zbiramo njene ugotovitve in najdene zapise
const
FPDF_ERR_PASSWORD = 4;
function AuditSecurity(const FileName: string;
Findings: TFindings): FPDF_DOCUMENT;
var
Perms: ULONG;
Revision: Integer;
begin
Result := FPDF_LoadDocument(PAnsiChar(AnsiString(FileName)), nil);
if Result = nil then
begin
if FPDF_GetLastError() = FPDF_ERR_PASSWORD then
Add(Findings, fsError, 'SEC-USERPW', 0,
'user (open) password required; audit cannot proceed')
else
Add(Findings, fsError, 'DOC-BROKEN', 0, 'file failed to parse');
Exit;
end;
Revision := FPDF_GetSecurityHandlerRevision(Result);
if Revision >= 0 then // -1 means the file is not encrypted
begin
// Opened with an empty password yet encrypted: owner-password-only.
// Anyone may read it, but the permission bits restrict what a
// conforming reader lets them do. Unencrypted files report all
// bits set, which is why the revision gate comes first.
Perms := FPDF_GetDocPermissions(Result);
Add(Findings, fsInfo, 'SEC-ENC', 0,
Format('encrypted, security handler revision %d', [Revision]));
if (Perms and 4) = 0 then // bit 3: print
Add(Findings, fsWarning, 'SEC-NOPRINT', 0,
'printing is not permitted');
if (Perms and 16) = 0 then // bit 5: copy / extract content
Add(Findings, fsInfo, 'SEC-NOCOPY', 0,
'content extraction is not permitted');
if (Perms and 2048) = 0 then // bit 12: high-resolution print
Add(Findings, fsWarning, 'SEC-LOWPRINT', 0,
'only low-resolution printing is permitted');
end;
end;
Maske prihajajo in so vzete neposredno iz tabele 22 standarda ISO 32000-1 (Table 22 of ISO 32000-1), ki prične šteti in označevati bite s številko 1: bit 3 same vrednosti /P prinaša dejansko masko 4, bit 5 je maska 16, bit 12 pa prinaša masko 2048. Ali je resnično določena ugotovitev in napaka zares pomembna in pomembna za nadaljnji tek stvari (matters), je odločitev o samem usmerjanju (routing decision). Tiskalni urad bi moral na sprejemnem mestu (at intake) vrniti datoteko s statusom SEC-NOPRINT nazaj tistemu, kateri jo je predal, kjer pošiljatelj dobi jasno sporočilo na preprost način (clear message), in pa seveda ne šele na neki enoti RIP šele tri ure pred rokom. Sistem ali proces shranjevanja in ohranjevanja oziroma preprost arhiv (An archive) bi moral ugotovitev SEC-ENC že kar samo po sebi obravnavati in upoštevati kot veliko blokado (blocker), glede na to, da samo šifriranje ter procesi neoviranega arhiviranja na dolgi rok (long-term preservation) ne morejo biti združljivi ali zmešani na noben smiseln in učinkovit način — ta točka preverjanja standarda je o tem jasna, takoj sedaj in formalno (is about to make formally)
Označevalci standardov: branje trditve ali zahteve PDF/A (reading a PDF/A claim)
Sama datoteka poda obvestilo in trditev (declares) glede njene skladnosti s standardom za PDF/A znotraj svojega in lastnega paketa s podatki z imenom XMP (XMP metadata packet), neposredno z uporabo njene lastnine pdfaid:part (z vrednostmi med 1 in 4) ter s klicem oblike pdfaid:conformance (črka nivoja ali ravni, na primer črka b za vizualno in oblikovno natančnost ali vrednost a za polno in popolno označevanje strukture in njenih tagov (structural tagging)). Zbirka funkcij in programska knjižnica oziroma API okolja in produkta PDFium v jeziku C (PDFium C API) na žalost ne vsebuje nobene enote za omogočen dostop do XMP podatkov (XMP accessor); element FPDF_GetMetaText ima pravico v branje oziroma procesira dejansko le slovar informacij o sami kodi ter se pri tem seveda povsem ustavi (reads only the Info dictionary), kar seveda ni lokacija in tudi ne vključuje same te identitete. Izhod v sili (escape hatch) se nahaja neposredno v standardu: oznaka in pravilo tipa ISO 19005 zahteva in obvezuje (requires), da se tok podatkov XMP vedno ohrani in shrani povsem nestisnjen in nekompresiran, točno zato, da lahko programi in pa sama programska in testna orodja poiščejo to določenost kar tako in povsem in zanesljivo brez (without a full) polnega PDF razčlenjevalnika. Hitro branje bajtov se potemtakem izkaže in predstavi (is therefore) v vlogi dejansko legitimnega in zanesljivega bralnika podatkov o tej zahtevi oziroma trditvi — vsaka datoteka, katere zahteva pa morda leži ujeta (hides inside) nekje globoko znotraj stisnjenega (compressed) toka podatkov, pa je v celoti gledano tisti isti naveden ali oklicani standard vsekakor že in zelo izrazito prekršila in razdrla s točno tem samim dejstvom oklica
function PdfAClaim(const FileName: string): string;
var
Bytes: TBytes;
S: RawByteString;
P, Limit: Integer;
begin
Result := ''; // empty = no PDF/A claim present
Bytes := TFile.ReadAllBytes(FileName);
if Length(Bytes) = 0 then
Exit;
SetString(S, PAnsiChar(@Bytes[0]), Length(Bytes));
P := Pos('pdfaid:part', S); // XMP identification schema
if P = 0 then
Exit;
// Handles both <pdfaid:part>2</pdfaid:part> and pdfaid:part="2":
// take the first digit after the property name.
Limit := Min(P + 32, Length(S));
Inc(P, Length('pdfaid:part'));
while (P <= Limit) and not (S[P] in ['1'..'4']) do
Inc(P);
if P <= Limit then
Result := 'PDF/A-' + Char(S[P]);
end;
Ugotovitev, ki jo to ustvari, je po naravi povsem namerno določena izključno samo zraven še kot informativnega značaja in to zato, ker ima trditev pomen povsem navadne izjave, vendar ne prinaša in hkrati ne zagotovi same lastnosti oziroma lastnine in prave karakteristike obravnavane datoteke. Zapis the vpis za XMP prinaša popolnoma vse pogoje samo na in za obseg enega (one line of) malega ukaza in ene in same proste in posamične vrstice standarda oblike XML (one line of XML), kakršnega koli (that any producer can write), celo tistega očitno pokvarjenega, z neustreznim zapisom ali formatom (including a broken one); usklajenost z dejanskim standardom se uresniči pa in seveda šele in samo pri sami datoteki, ki dejansko spoštuje, pregleduje (satisfying) stotine ali celo stotine resničnih in zavezujočih pogojev ali pravil zavez glede ohranjenih ali teh vdelanih (embedded) oblik pisave ali tipov pisav, barve, ki je povsem prepoznavna, stalno ločena ali vsaj ne odvisna pri teh ločenih barvah naprav pri izbiranju (device-independent color), in prav tako tudi pogojev (rules) prepovedanih vrst značilnosti, funkcionalnosti ali in orodij funkcij opreme (forbidden features). Odkrivanje the (Detecting the claim) ali te izjave oz. trditve zgolj razkrije in preprosto na hitro opozori programerja in the usmerja aplikacije or the orodja aplikacijo (tells you which files to route) proti nadaljnjem usmerjanju takšnih dokumentov ali prijav k čisto or the to sami navadni v or testni oz. resnični na the za (real) validaciji the same vrste the on (real validation), the ter povsem in točno The na za res čisto (and nothing more) nič dodatnega. Motor the or za The the ali the predprocesor na na the the na ali z v or z The v the the na za (The component's built-in preflight engine) iz or or za the ali the v the or na (performs that validation) on na za in v or (across PDF/A, PDF/UA, and PDF/X profiles, and članek za batch CLI pojasnjuje (shows how to wire it) implementacijo the z the na The na on the (into a pipeline with reports) the an in the or or the za z na na the (an auditor can open later)
Zagon (A run) or the ob the on z (against a problem file)
Gonilnik (The driver) v or on or on v (strings the checks together): the The ali in na na v in or na varnost or (security first), The on za the or v on in na na (because it decides whether the audit runs at all), in the na on the za or (then document-level behaviors and the standards claim), or in na v the (then a page loop for actions and images)
function AuditFile(const FileName: string; Findings: TFindings): Integer;
var
Doc: FPDF_DOCUMENT;
Page: FPDF_PAGE;
I: Integer;
Claim: string;
begin
Doc := AuditSecurity(FileName, Findings);
if Doc = nil then
Exit(2); // audit failure, not a verdict
try
AuditDocumentBehaviors(Doc, Findings);
Claim := PdfAClaim(FileName);
if Claim <> '' then
Add(Findings, fsInfo, 'STD-PDFA', 0,
Claim + ' conformance claimed (declaration only, not validated)');
for I := 0 to FPDF_GetPageCount(Doc) - 1 do
begin
Page := FPDF_LoadPage(Doc, I);
if Page = nil then
begin
Add(Findings, fsError, 'PAGE-BROKEN', I + 1, 'page failed to parse');
Continue;
end;
try
AuditPageActions(Doc, Page, I + 1, Findings);
AuditPageImages(Page, I + 1, Findings);
finally
FPDF_ClosePage(Page);
end;
end;
finally
FPDF_CloseDocument(Doc);
end;
if Findings.Count > 0 then
Result := 1
else
Result := 0;
end;
Proti in z the na the the on (Against) brošuri, na or the the na v or (a brochure that came back from an outside agency), on or na the on the the in the za or the (the output looks like this):
> preflight_audit brochure_final.pdf
brochure_final.pdf: 5 finding(s)
[ERROR] ACT-LAUNCH page 3 Launch action targets "..\tools\setup.exe"
[ERROR] JS-DOC doc 2 document-level JavaScript action(s) run on open
[WARNING] IMG-LOWRES page 7 image 412x287 px placed at 396.0x275.8 pt = 75 DPI effective
[WARNING] SEC-NOPRINT doc printing is not permitted
[INFO] STD-PDFA doc PDF/A-2 conformance claimed (declaration only, not validated)
exit code 1
Vsaka posamezna vrstica je popolnoma samostojno operativna (actionable on its own), vendar je šele in dejansko njuna kombinacija prava in resnična razsodba (real verdict). Ta datoteka ima trditev z zahtevo za standard PDF/A-2 (claims PDF/A-2), čeprav sočasno in na drugi strani nosi in vključuje slovar za šifriranje ter na tem dejansko aktiven oziroma živ (live) JavaScript, in vse to taisti standard PDF/A absolutno strogo prepoveduje in preprečuje (forbids both outright) — zatorej je njena prejšnja trditev že dokazljivo popolnoma lažna na prvem pregledu, še preden se resno prične (before any deep validator runs). To pa je tista vrsta protislovja (contradiction), kakršno ravan in navaden (flat) seznam ugotovitev jasno in odkrito razkrije (surfaces) in enostaven booleov (boolean) rezulat uspeh/neuspeh ali da/ne preprosto skrije
Česa vam ta revizija preprosto ne more povedati (What this audit cannot tell you)
Poštenost pri določanju samega področja ali obsega delovanja in pregledovanja (Honesty about scope) je natanko tisto, kar ohranja zaupanje v takšno orodje preflight. Vse zgoraj navedeno prebere zgolj tisto, kar datoteka dejansko sama izjavlja in trdi o sebi (declares about itself): orodje PDFium dejansko razčleni njeno strukturo, ta ista revizija pa preveri njen inventar (inventories it). Ne izvaja (It does not perform) nobene resnične validacije in preverjanja za standard PDF/A — ne vključuje nobenih testiranj glifov (glyph-coverage checks) zoper te vdelane ali shranjene tipe pisav, nobenih preverb ali analiz samega barvnega prostora za prave namere in smeri končnega prikaza ali izhoda (output intents), ne določa in sploh nobenega od pogojev na tako imenovani ravni same klavzule, kakršen šele in ob koncu res ločuje navadno lažno izjavo in trditev od prave skladnosti (conformance); za takšno in še bolj podrobno preverjanje pa je seveda obvezno potreben namenski validator (dedicated validator), kot sta na primer komercialni mehanizem komponente (The component's built-in preflight engine) ali veraPDF. Biti in kodi dovoljenj (Permission bits) so seveda tukaj zgolj in povsem v funkciji čistih namenov oz. izjav (declarations), ki jih taisti bralniki seveda dosledno spoštujejo (honor), vendar vsekakor in strogo to ne predstavlja pravega in trdnega šifrirnega ali varnostnega kriptografskega zidu oziroma prepovedi, zato podatek SEC-NOPRINT opisuje zgolj navaden namen oziroma željo po namenu (intent) namesto kakršnekoli izvedbe oziroma same prave izvršbe (enforcement). Skeniranje dejanj zajema vse označene povezave in skripte na ravni dokumenta (link annotations and document-level scripts); tisti skripti, ki so zakopani v slovarje dogodkov v poljih obrazcev (scripts buried in form-field event dictionaries), pa poleg tega potrebujejo še API-je za obrazce. Tudi preverjanje podpisov, v primeru da z njim razširite svojo revizijo, poroča le o oklicani ali trditveni nameri, ne o potrjeni in validirani kriptografiji — veljavnost potrditve same verige certifikatov (certificate chain validation) ostaja povsem ločena in samostojna naloga. Revizija preflight predstavlja zgolj vhodni intervju (intake interview), in ne končnega preizkusa ali sodišča (trial): njeno glavno delo in namen je, da naredi odločitev o rutiranju oziroma o usmeritvi (routing decision) informirano (informed), hitro (fast) in pa povsem in preprosto ponovljivo (repeatable)
Opomba: API-ji dokumentov, strani, zaznamkov (annotation) in slikovnih objektov (image object APIs), ki so bili uporabljeni skozi to celotno revizijo, se seveda povsem ujemajo in pošiljajo skupaj (ship with) z izjemno visokonivojskim programskim ovojem za jezik Delphi (high-level Delphi wrapper) in seveda z vgrajenim, polnim orodjem in motorjem za validacijo standardov, znotraj rešitve PDFium Component