Üretim sınırına —bir yazdırma kuyruğuna, bir arşive, bir müşteri yükleme portalına— ulaşan bir PDF, hiçbir şey onu oluşturmadan (render) önce denetlenmelidir. Dosya harici bir programı başlatmak üzere ayarlanmış bir Başlat (Launch) eylemi, yazdırılamayacak kadar kaba (coarse) görüntüler, teslim edildiği yazdırma işini yasaklayan bir şifreleme sözlüğü veya uymadığı bir PDF/A etiketi taşıyabilir. Bir belgeyi bir iş akışına girmeden önce bu gibi kurallara karşı incelemeye ön kontrol (preflighting) adı verilir ve PDFium C API'si, Delphi'ye tek bir sayfayı bile oluşturmadan (render) kontrolleri doğrudan uygulamak için gereken her şeyi verir
Bu makale denetimlerin kendisini oluşturur: her biri bulguları (findings) paylaşılan bir sonuç listesine ekleyen küçük bir rutin olan dört denetim sınıfı. Etkileşimli öğeler, kaynak metrikleri, güvenlik durumu ve standart işaretçilerinin tümü, aritmetik de dahil olmak üzere çalışan kod elde eder. İhtiyacınız olan şey kontrollerin etrafındaki mekanizmaysa —toplu (batch) klasör döngüleri, JSON ve HTML rapor dosyaları, dosya başına izolasyon— PDFium Bileşeni (Component) hazır bir ön kontrol (preflight) motoruyla birlikte gönderilir ve toplu ön kontrol CLI makalesi bu tesisatı kapsar. İkisi, tek bir çıkış kodu kelime dağarcığını (exit-code vocabulary) kasıtlı olarak paylaşır, bu nedenle burada yazılan bir denetçi doğrudan bu toplu iş sürücüsünün (batch driver) altına yerleştirilir
Bulgu kaydı ve çıkış kodu sözleşmesi
Her kontrol tek bir düz kayıt türüne (flat record type) yazar, çünkü alternatif olan her kontrolün kendi düz yazısını yazdırması sayılamaz, filtrelenemez veya daha sonra eşiklenemez (thresholded). Dört alan yeterlidir
uses
System.SysUtils, System.Math, System.IOUtils,
System.Generics.Collections, pdfium_lib;
type
TFindingSeverity = (fsInfo, fsWarning, fsError);
TPreflightFinding = record
Severity: TFindingSeverity;
Code: string; // kararlı makine anahtarı, örn. 'ACT-LAUNCH'
Page: Integer; // 1 tabanlı; 0 belge düzeyi anlamına gelir
Message: string; // insanlar için; sürümler arasında yeniden yazmakta özgür
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;
Aşağı akış (Downstream) araçları Message metninde değil, Code üzerinde anahtarlanır; metin değişmekte serbesttir. Süreç çıkış kodu (process exit code) toplu iş (batch) makalesiyle aynı üç değerli sözleşmeyi izler: 0 dosyanın bulgu (finding) üretmediği anlamına gelir, 1 bulgu olduğu anlamına gelir ve 2 dosya ayrıştırılamadığı veya bir parola gerektirdiği için denetimin (audit) kendisinin çalıştırılamadığı anlamına gelir. Kod 2'yi ayrı tutmak önemlidir. Bozuk taramalardan (scans) oluşan bir klasör, ani bir uyumluluk çöküşü (compliance collapse) değil, akış yukarısındaki (upstream) bozuk bir tarayıcıdır ve ikisini bir araya getirmek birisinin yanlış sorunun peşine düşmesine neden olur
Etkileşimli öğeler: komut dosyaları, başlatma hedefleri, dış bağlantılar
PDFium bulduğu her eylemi (action) bir tamsayı türüne göre sınıflandırır ve fpdf_doc.h'deki sabitleri (constants) tam olarak sabitlemeye (pin down) değer, çünkü yanlış kopyalanmış değerler bir tarayıcıyı (scanner) sessizce kör eder. Gerçek numaralandırma PDFACTION_UNSUPPORTED = 0, PDFACTION_GOTO = 1, PDFACTION_REMOTEGOTO = 2, PDFACTION_URI = 3, PDFACTION_LAUNCH = 4 ve PDFACTION_EMBEDDEDGOTO = 5 şeklindedir. Neyin olmadığına dikkat edin: JavaScript üyesi yoktur. Belge düzeyindeki betikler (scripts) bağlantı eylemleri (link actions) değildir ve asla FPDFAction_GetType üzerinden görünmezler; ayrı bir çağrı ailesi tarafından numaralandırılırlar. Hayal edilmiş bir JavaScript sabitine karşı eylem türlerini test eden bir denetçi sonsuza kadar derler, çalışır ve hiçbir şey bulamaz
const
PDFACTION_GOTO = 1; // belge içi atlama: zararsız
PDFACTION_REMOTEGOTO = 2; // başka bir yerel dosyaya atlama
PDFACTION_URI = 3; // harici bir URL açar
PDFACTION_LAUNCH = 4; // harici bir program başlatır
PDFACTION_EMBEDDEDGOTO = 5; // gömülü bir dosyaya atlama
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; // yalnızca hedefe yönelik bağlantı, işaretlenecek bir şey yok
AType := FPDFAction_GetType(Action);
case AType of
PDFACTION_LAUNCH:
Add(Findings, fsError, 'ACT-LAUNCH', PageNo,
'Başlat (Launch) eylemi "' + ActionTarget(Doc, Action, AType) + '" hedefliyor');
PDFACTION_URI:
Add(Findings, fsWarning, 'ACT-URI', PageNo,
'bağlantı (link) şunu açıyor: ' + ActionTarget(Doc, Action, AType));
PDFACTION_REMOTEGOTO, PDFACTION_EMBEDDEDGOTO:
Add(Findings, fsWarning, 'ACT-XFILE', PageNo,
'dosyalar arası (cross-file) hedef "' + ActionTarget(Doc, Action, AType) + '"');
end; // PDFACTION_GOTO tasarımı gereği sessiz kalır
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 belge düzeyinde JavaScript eylemi açılışta çalışıyor', [N]));
N := FPDFDoc_GetAttachmentCount(Doc);
if N > 0 then
Add(Findings, fsWarning, 'ATT-EMB', 0,
Format('%d gömülü dosya eki', [N]));
end;
Önem derecesi (severity) bölünmesi (split), politikayı kodlar. Bir Başlat (Launch) eylemi bir hatadır çünkü rastgele bir programı başlatmak, bir PDF'deki bir tıklamanın yapabileceği en tehlikeli şeydir ve hiçbir faturanın buna ihtiyacı yoktur. Harici URI'ler uyarılardır (warnings): meşru (legitimate) belgelerde yaygındır, ancak görünür bağlantı metni ile gerçek hedefin eşleşmesi gerekmediğinden, bir gözden geçiren (reviewer) hedefi tıklamadan görmelidir. Belge içi Git (GoTo) atlamaları davranış değil, yapıdır ve raporda tamamen yer almaz —her içindekiler tablosu (table-of-contents) girişinde (entry) yalan yere bağıran bir ön kontrol (preflight), insanları onu görmezden gelmeleri için eğitir. JavaScript sayımının (count) arkasındaki betik (script) gövdelerini okumak ve imza (signature) MDP düzeyleri ile XFA tespiti (detection) için, güvenlik riski denetimi makalesi aynı yüzeyde bileşenin nesne sarmalayıcısı (object wrapper) aracılığıyla yürür
Kaynak metrikleri: etkili görüntü DPI'sı
Bir PDF'in içindeki görüntünün kendine ait bir DPI'sı yoktur. Pikselleri vardır ve sayfa bu pikselleri nokta (points) cinsinden ölçülen bir dikdörtgene yerleştirir, burada 72 nokta bir inç (inch) oluşturur. Çözünürlük (Resolution) yalnızca ikisinin oranı (ratio) olarak vardır, bu nedenle aynı 600'e 400 fotoğraf küçük resim (thumbnail) olarak keskin, tam sayfa kahraman (hero) olarak ise bulanık (blurry) bir karmaşadır. Bu nedenle denetimin (audit) her görüntü için her iki sayıya da ihtiyacı vardır: görüntü meta verilerinden (metadata) kaynak piksel boyutları ve nesne sınırlarından (bounds) yerleştirilen (placed) dikdörtgen
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; // sayfadaki yerleştirilmiş (placed) boyut, nokta (points) cinsinden
HeightPt := T - B;
if (WidthPt <= 0) or (HeightPt <= 0) or
(Meta.Width = 0) or (Meta.Height = 0) then
Continue;
// 72 nokta (points) = 1 inç (inch), yani yerleştirilen inç = noktalar / 72 ve
// etkili (effective) DPI = kaynak pikseller / yerleştirilen inç.
DpiX := Meta.Width / (WidthPt / 72.0);
DpiY := Meta.Height / (HeightPt / 72.0);
EffDpi := Min(DpiX, DpiY); // daha kötü olan eksen, baskı kalitesini belirler
if EffDpi < 150.0 then
Add(Findings, fsWarning, 'IMG-LOWRES', PageNo,
Format('görüntü %dx%d px %.1fx%.1f pt boyutunda yerleştirilmiş = etkili DPI %.0f',
[Meta.Width, Meta.Height, WidthPt, HeightPt, EffDpi]))
else if EffDpi > 600.0 then
Add(Findings, fsInfo, 'IMG-BLOAT', PageNo,
Format('görüntü yerleştirilen boyutta %.0f DPI; yeniden örnekleme (resampling) ' +
'görünür bir kayıp olmadan dosya boyutunu küçültebilir', [EffDpi]));
end;
end;
Eşikler (thresholds) fizik değil, politikadır: 150 DPI, altında ofis baskısının gözle görülür şekilde piksellendiği (pixelates) bir tabandır, 300 olağan ticari hedeftir ve 600'ün üzerindeki herhangi bir şey görünür kalite sağlamazken dosya boyutunu şişirir (inflates), bu yüzden kusur (defect) yerine bilgi amaçlı şişkinlik (informational bloat) olarak raporlanır. Dürüst bir uyarı: FPDFPageObj_GetBounds eksen hizalı (axis-aligned) kutuyu döndürür, bu nedenle döndürme ile (with rotation) yerleştirilen bir görüntü için hesaplanan değer gerçek yoğunluğu hafife alır. FPDF_IMAGEOBJ_METADATA yapısı (struct) ayrıca PDFium'un tam dönüştürme matrisinden (transform matrix) türettiği horizontal_dpi ve vertical_dpi alanlarını taşır ve iki sonucu karşılaştırmak, döndürülmüş (rotated) yerleşimleri tespit etmenin ucuz bir yoludur. Aynı noktadan piksele aritmetiği (points-to-pixels arithmetic), JPEG dışa aktarma makalesinde ele alınan işlemeyi zıt yönde yönlendirir
Güvenlik durumu: şifreleme ve izin bitleri
PDF şifrelemesi (encryption) farklı işleri olan iki parola tanımlar. Kullanıcı parolası (user password) şifre çözmeyi (decryption) kapılandırır (gates): onsuz dosya hiç açılmaz ve FPDF_LoadDocument, FPDF_GetLastError FPDF_ERR_PASSWORD raporlayarak nil döndürür. Sahip parolası (owner password) izinleri (permissions) kapılandırır: yalnızca bir sahip parolası ile korunan bir dosya hiçbir kimlik bilgisi olmadan açılır, ancak uyumlu (conforming) bir okuyucunun (reader) onurlandırması (honor) gereken kısıtlama (restriction) bitlerini taşır. Bu nedenle yükleme denemesinin (load attempt) kendisi ilk güvenlik araştırmasıdır (probe) ve ayrım, çıkış kodunu belirler —kullanıcı parolası olan bir dosya denetlenemez (kod 2), oysa sahip parolası olan bir dosya normal şekilde denetlenir ve yalnızca bulguları (findings) biriktirir
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,
'kullanıcı (açık) parolası gerekiyor; denetim (audit) devam edemiyor')
else
Add(Findings, fsError, 'DOC-BROKEN', 0, 'dosya ayrıştırılamadı (failed to parse)');
Exit;
end;
Revision := FPDF_GetSecurityHandlerRevision(Result);
if Revision >= 0 then // -1 dosyanın şifrelenmediği (not encrypted) anlamına gelir
begin
// Boş bir parolayla açıldı ama şifreli: yalnızca sahip parolası (owner-password-only).
// Herkes okuyabilir, ancak izin bitleri uyumlu bir okuyucunun
// onlara ne yapmalarına izin verdiğini kısıtlar. Şifrelenmemiş (unencrypted) dosyalar tüm
// bitlerin (bits set) ayarlandığını raporlar, bu yüzden revizyon kapısının (revision gate) önce gelmesinin nedeni budur.
Perms := FPDF_GetDocPermissions(Result);
Add(Findings, fsInfo, 'SEC-ENC', 0,
Format('şifrelenmiş (encrypted), güvenlik işleyicisi (security handler) revizyonu %d', [Revision]));
if (Perms and 4) = 0 then // bit 3: yazdır (print)
Add(Findings, fsWarning, 'SEC-NOPRINT', 0,
'yazdırmaya (printing) izin verilmiyor');
if (Perms and 16) = 0 then // bit 5: kopyala / içeriği ayıkla (copy / extract content)
Add(Findings, fsInfo, 'SEC-NOCOPY', 0,
'içerik ayıklamaya (content extraction) izin verilmiyor');
if (Perms and 2048) = 0 then // bit 12: yüksek çözünürlüklü yazdırma (high-resolution print)
Add(Findings, fsWarning, 'SEC-LOWPRINT', 0,
'yalnızca düşük çözünürlüklü yazdırmaya izin veriliyor');
end;
end;
Maskeler, ISO 32000-1'in 1'den bitleri numaralandıran Tablo 22'sinden gelir: /P değerinin 3. biti maske 4'tür, 5. bit 16'dır, 12. bit 2048'dir. Verilen bir bulgunun (finding) önemli olup olmadığı bir yönlendirme (routing) kararıdır. Bir baskı bürosu, teslim edenin (submitter) son teslim tarihinden (deadline) üç saat önce RIP'de değil de net bir mesaj aldığı alımda (intake) bir SEC-NOPRINT dosyasını geri çevirmelidir (bounce). Şifreleme (encryption) ve uzun vadeli (long-term) koruma uyuşmadığından (standartlar denetiminin resmen yapmak üzere olduğu bir nokta), bir arşiv SEC-ENC'nin kendisini engelleyici (blocker) olarak ele almalıdır
Standart işaretçileri: PDF/A iddiasını okumak
Bir dosya, pdfaid:part özelliği (1 ila 4) ve pdfaid:conformance (görsel aslına uygunluk (visual fidelity) için b veya tam yapısal etiketleme (full structural tagging) için a gibi seviye harfi) aracılığıyla XMP meta veri (metadata) paketinde PDF/A uygunluğunu (conformance) beyan eder (declares). PDFium'un C API'si hiçbir XMP erişimcisi (accessor) sunmaz; FPDF_GetMetaText yalnızca kimlik bilgilerinin (identification) yaşamadığı Info sözlüğünü (dictionary) okur. Kaçış kapağı (escape hatch) standardın kendisindeki bir kuraldır: ISO 19005, XMP meta veri akışının (stream), tam da araçların tam bir PDF ayrıştırıcısı (parser) olmadan bulabilmesi için sıkıştırılmamış (uncompressed) olarak saklanmasını gerektirir. Bu nedenle, ham (raw) bir bayt taraması meşru (legitimate) bir iddia dedektörüdür (claim detector) —ve iddiası sıkıştırılmış bir akışın (compressed stream) içinde saklanan bir dosya iddia ettiği standardı (standard) zaten ihlal etmiştir
function PdfAClaim(const FileName: string): string;
var
Bytes: TBytes;
S: RawByteString;
P, Limit: Integer;
begin
Result := ''; // empty = hiçbir PDF/A iddiası (claim) mevcut değil
Bytes := TFile.ReadAllBytes(FileName);
if Length(Bytes) = 0 then
Exit;
SetString(S, PAnsiChar(@Bytes[0]), Length(Bytes));
P := Pos('pdfaid:part', S); // XMP kimlik doğrulama şeması (identification schema)
if P = 0 then
Exit;
// Hem <pdfaid:part>2</pdfaid:part> hem de pdfaid:part="2" öğelerini işler:
// özellik (property) adından sonraki ilk basamağı alır.
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;
Bunun ürettiği bulgu (finding) kasıtlı olarak bilgilendirme amaçlıdır (informational), çünkü bir iddia (claim) dosyanın bir özelliği değil, bir beyandır (declaration). XMP girişi, bozuk bir (broken) üretici (producer) de dahil olmak üzere herhangi bir üreticinin yazabileceği bir XML satırıdır; uygunluk (conformance), dosyanın (file) gömülü yazı tipleri (embedded fonts), cihaza bağımsız renk (device-independent color) ve yasaklanmış (forbidden) özellikler (features) hakkındaki yüzlerce (hundreds of) kuralı (rules) gerçekten karşılamasıdır (satisfying). İddiayı (claim) tespit etmek (detecting) size yalnızca hangi dosyaları (files) gerçek (real) doğrulamaya (validation) yönlendireceğinizi söyler (tells you), fazlasını değil. Bileşenin (component) yerleşik ön kontrol motoru (built-in preflight engine), bu doğrulamayı PDF/A, PDF/UA ve PDF/X profilleri (profiles) üzerinden (across) gerçekleştirir (performs) ve toplu iş (batch) CLI makalesi (article) onu bir denetçinin (auditor) daha sonra açabileceği (can open later) raporlarla (reports) bir işlem hattına (pipeline) nasıl bağlayacağınızı (wire) gösterir (shows)
Sorunlu bir dosyaya karşı bir çalıştırma
Sürücü (driver) kontrolleri birbirine bağlar: önce güvenlik, çünkü denetimin (audit) hiç çalışıp çalışmayacağına (runs at all) karar verir, ardından belge düzeyi davranışlar (document-level behaviors) ve standartlar iddiası (standards claim), daha sonra eylemler (actions) ve görüntüler (images) için bir sayfa döngüsü (page loop)
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); // denetim (audit) hatası, bir karar (verdict) değil
try
AuditDocumentBehaviors(Doc, Findings);
Claim := PdfAClaim(FileName);
if Claim <> '' then
Add(Findings, fsInfo, 'STD-PDFA', 0,
Claim + ' uygunluğu beyan edildi (conformance claimed) (yalnızca beyan (declaration only), doğrulanmadı (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, 'sayfa ayrıştırılamadı (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;
Dışarıdaki bir ajanstan dönen bir broşüre karşı, çıktı şöyle görünür:
> preflight_audit brochure_final.pdf
brochure_final.pdf: 5 bulgu(lar) (finding(s))
[ERROR] ACT-LAUNCH sayfa 3 Başlat (Launch) eylemi "..\tools\setup.exe" hedefini gösteriyor
[ERROR] JS-DOC doc 2 belge düzeyinde JavaScript eylemi açılışta çalışıyor
[WARNING] IMG-LOWRES sayfa 7 412x287 piksel resim, 396.0x275.8 pt'ye yerleştirilmiş = 75 DPI etkili (effective)
[WARNING] SEC-NOPRINT doc yazdırmaya (printing) izin verilmiyor
[INFO] STD-PDFA doc PDF/A-2 uygunluğu (conformance) iddia ediliyor (yalnızca beyan, doğrulanmadı)
çıkış kodu 1
Her satır kendi başına eyleme geçirilebilirdir, ancak asıl karar kombinasyondur. Bu dosya bir şifreleme (encryption) sözlüğü ve canlı JavaScript taşırken PDF/A-2 olduğunu iddia ediyor ve PDF/A her ikisini de açıkça yasaklıyor —bu nedenle, hiçbir derin doğrulayıcı çalışmadan önce iddianın (claim) yanlış olduğu kanıtlanabilir. Bu, düz (flat) bir bulgu (findings) listesinin ortaya çıkardığı (surfaces) ve boole değerindeki geçme/kalmanın (pass/fail) gizlediği (hides) bir tür çelişkidir (contradiction)
Bu denetimin size söyleyemeyeceği şeyler
Kapsam (scope) konusunda dürüst (honesty) olmak, bir ön kontrol (preflight) aracının güvenilir kalmasını sağlayan şeydir. Yukarıdaki her şey dosyanın (file) kendisi hakkında (about itself) beyan ettiklerini (declares) okur: PDFium yapıyı (structure) ayrıştırır (parses) ve bu denetim (audit) onun envanterini (inventories) çıkarır. PDF/A doğrulamasını (validation) gerçekleştirmez (perform) —gömülü (embedded) yazı tiplerine (fonts) karşı glif kapsamı (glyph-coverage) denetimi yoktur (no), çıktı amaçlarına (output intents) karşı renk uzayı analizi (color space analysis) yoktur (no), bir iddiayı (claim) uyumluluktan (conformance) ayıran madde düzeyindeki kuralların (clause-level rules) hiçbiri yoktur; bunun için bileşenin (component) ön kontrol (preflight) motoru veya veraPDF gibi özel (dedicated) bir doğrulayıcıya (validator) ihtiyacınız vardır (need). İzin bitleri (Permission bits) kriptografik duvarlar değil, uyumlu (conforming) okuyucuların onurlandırdığı (honor) beyanlardır (declarations), bu nedenle SEC-NOPRINT uygulamadan ziyade niyeti (intent) açıklar (describes). Eylem (action) taraması bağlantı açıklamalarını (link annotations) ve belge düzeyindeki komut dosyalarını (document-level scripts) kapsar; form alanı etkinlik sözlüklerine (form-field event dictionaries) gömülü (buried) komut dosyalarının (scripts) üstte form API'lerine (form APIs) ihtiyacı (need) vardır. Ve eğer (if) denetimi (audit) biriyle (one) genişletirseniz (extend), bir imza (signature) kontrolü doğrulanmış şifrelemeyi (verified cryptography) değil, beyan edilen niyeti (declared intent) bildirir (reports) — sertifika (certificate) zinciri (chain) doğrulaması ayrı (separate) bir iştir (job). Ön kontrol (preflight) denetimi (audit), duruşma (trial) değil alım mülakatıdır (intake interview): görevi (job) yönlendirme (routing) kararını (decision) bilinçli (informed), hızlı (fast) ve tekrarlanabilir (repeatable) hale getirmektir
Not: Bu denetim boyunca kullanılan belge, sayfa, not (annotation) ve görüntü nesnesi API'leri, yüksek seviyeli (high-level) bir Delphi sarmalayıcısı (wrapper) ve eksiksiz bir standart doğrulama (standards-validation) ön kontrol motoruyla (preflight engine) birlikte, PDFium Bileşeni (Component) ile birlikte gönderilir