Um PDF que chega a uma fronteira de produção — uma fila de impressão, um arquivo, um portal de carregamento de clientes — deve ser auditado antes que algo o renderize. O ficheiro pode transportar uma ação Launch configurada para iniciar um programa externo, imagens demasiado grosseiras para sobreviverem à impressão, um dicionário de encriptação que proíbe o próprio trabalho de impressão para o qual foi submetido ou um rótulo PDF/A que não cumpre. A inspeção de um documento perante regras como estas antes de ele entrar num fluxo de trabalho (workflow) é designada por preflighting (verificação prévia), e a API C do PDFium fornece ao Delphi tudo o que é necessário para implementar as verificações diretamente, sem renderizar uma única página
Este artigo constrói as verificações em si: quatro classes de auditoria, sendo cada uma delas uma pequena rotina que anexa (appends) as descobertas (findings) a uma lista de resultados partilhada. Elementos interativos, métricas de recursos, estado de segurança e marcadores de normas obtêm todos código funcional, incluindo a aritmética. Se aquilo de que necessita é do mecanismo em torno das verificações — ciclos (loops) de lote em pastas (batch folder), ficheiros de relatório JSON e HTML, isolamento por ficheiro — o Componente PDFium traz integrado um motor de preflight pronto a usar, e o artigo sobre a CLI de preflight em lote abrange esse mecanismo subjacente (plumbing). Os dois partilham deliberadamente um vocabulário de códigos de saída (exit codes), para que um auditor aqui escrito encaixe perfeitamente debaixo desse controlador em lote (batch driver)
O registo de descobertas (finding record) e o contrato de códigos de saída (exit codes)
Cada verificação escreve para um único tipo de registo simples (flat record type), porque a alternativa, em que cada verificação imprime a sua própria prosa, não pode ser contada, filtrada ou submetida a limiares (thresholded) a posteriori. Quatro campos são suficientes
uses
System.SysUtils, System.Math, System.IOUtils,
System.Generics.Collections, pdfium_lib;
type
TFindingSeverity = (fsInfo, fsWarning, fsError);
TPreflightFinding = record
Severity: TFindingSeverity;
Code: string; // chave de máquina estável, por ex. 'ACT-LAUNCH'
Page: Integer; // baseado em 1; 0 significa ao nível do documento
Message: string; // para humanos; livre para ser reescrita entre lançamentos (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;
As ferramentas a jusante (downstream tooling) baseiam-se em Code, nunca no texto Message, que é passível de ser alterado. O código de saída do processo segue o mesmo contrato de três valores do artigo sobre o lote (batch): 0 significa que o ficheiro não produziu descobertas, 1 significa que existem descobertas e 2 significa que a própria auditoria não pôde ser executada porque o ficheiro falhou a análise (parsing) ou exige uma palavra-passe. Manter o código 2 em separado tem relevância. Uma pasta com digitalizações corrompidas revela que existe um scanner avariado a montante, não um colapso súbito da conformidade, e misturar ambos leva alguém a ir atrás do problema errado
Elementos interativos: scripts, alvos de lançamento, links externos
O PDFium classifica cada ação que encontra através de um tipo de número inteiro, e vale a pena definir com precisão as constantes de fpdf_doc.h, visto que os valores copiados erradamente tornam um scanner cegamente silencioso. A verdadeira enumeração é PDFACTION_UNSUPPORTED = 0, PDFACTION_GOTO = 1, PDFACTION_REMOTEGOTO = 2, PDFACTION_URI = 3, PDFACTION_LAUNCH = 4 e PDFACTION_EMBEDDEDGOTO = 5. Note no que se encontra ausente: não existe um membro JavaScript. Os scripts ao nível do documento não são ações de links e nunca aparecem através de FPDFAction_GetType; eles são enumerados por uma família de chamadas em separado. Um auditor que teste tipos de ação perante uma constante JavaScript imaginada é compilado, executado e nunca encontra nada
const
PDFACTION_GOTO = 1; // salto no documento: inofensivo
PDFACTION_REMOTEGOTO = 2; // salto para outro ficheiro local
PDFACTION_URI = 3; // abre um URL externo
PDFACTION_LAUNCH = 4; // inicia um programa externo
PDFACTION_EMBEDDEDGOTO = 5; // salto para um ficheiro incorporado
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; // link apenas de destino, nada a assinalar
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 mantém-se em silêncio por definição (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;
A divisão por gravidade codifica políticas. Uma ação Launch consubstancia um erro porque iniciar e encetar a partida de um programa arbitrário perfila a coisa mais temerária que um clique encarnado num PDF é passível de fazer, e nenhuma fatura carece disso. Os URI externos assumem-se na vertente de avisos (warnings): vulgares em documentos lícitos, contudo o avaliador encarregue das devidas inspeções carece de desvendar a perscrutação do alvo descurando do efetivo clique, já que o aspeto patente do texto visível na ligação nem sempre pauta pela equivalência encetada face ao destino verídico. Os saltos GoTo no seio do documento pautam a estrutura descurando dos contornos a moldarem as balizas no comportamento, não aflorando percurso que conste por onde resida em registo no seio afeto ao relatório — um preflight assente a desencadear o alerta sem motivo no tocante às entradas constantes do índice molda condutas nas pessoas impelindo a encetar via de recusa e a ignorá-lo de modo categórico. Para efetuar e percorrer em leitura a vertente contendo os blocos de script (script bodies) alocados nas imediações inerentes aos alicerces do cálculo atinente ao JavaScript, bem como para perscrutar domínios afetos e vocacionados para a deteção perante níveis de assinatura MDP e a sua vertente face à tecnologia materializada sob as matrizes subscritas do modelo XFA, o artigo pautando pela elaboração de domínios vocacionados perante auditoria balizada a assumir as perscrutações e providências perante as vertentes a preencher face a riscos encetados sob a alçada de cariz respeitando a segurança acompanha, enquadra e preenche a abordagem percorrendo e efetivando com a idêntica face sem disrupção perfazendo exatamente o mesmo perfil e alicerce de matriz enquadrando via pelo revestimento (object wrapper) correspondente ao próprio componente
Métricas de recursos: DPI de imagem efetivo
Uma imagem no seio abrigado nas guisas encetando a formatação no interior de um PDF atua de raiz descurando perante propensão dotada para que porte origens orientando qualquer DPI (pontos por polegada) da sua própria matriz, uma vez que, para dizer a verdade e assentar perante a exata vertente sem sombra nem engodos, os domínios afiançados revestindo os contornos da sua verdadeira origem enquadram provimento e efetivam as bases dotadas e distribuídas nos pormenores preenchendo as matrizes de píxeis (pixels). A partir dali assinalam percurso com rumos em prol das vias encarregues onde as imediações enquadradas subscrevem os desígnios para os papéis onde os providenciam onde cabe no seio da página posicionar tais píxeis inseridos nos contornos de um retângulo medido com subordinação na unidade expressa através de pontos (points), reduto na esteira do qual um preceito de 72 pontos compõem a exata base que define materializando uma polegada. A resolução na devida perspetiva tem no cômputo dotado a base e o fim na existência por onde assume percurso e vigora apenas materializando a vertente da relação encetada assumindo e perfilando as proporções imbuídas perante a relação e razão que interliga os propósitos dos dois supracitados, consistindo aqui no motivo que serve perante as vias e instâncias que consagram e subscrevem propósitos para as guisas a comprovarem e ilustrarem exímiamente a exata razão encarregue de ser providenciada balizando as exatas bases, vertentes e alicerces na subordinação providenciando o facto atinente a que aquela dita, certa, inequívoca e exata, mesma fotografia assente na sua distribuição perfilada preenchendo as premissas em 600 por 400 encarne e desempenhe um papel moldado a revestir na guisa a atuar na face consubstanciada e preenchida num registo onde demonstra provimento na via dotada mediante valências de impecável nitidez dotada para um recorte digno de lâmina sob os moldes correspondendo a assumir a matriz de miniatura por contraponto em vias contrárias por onde no limite consubstanciado perfila as instâncias em guisa a ditar em vias e domínios enquadrando num registo que no final acaba a revestir encarnando na forma assumindo na fisionomia e silhueta um conjunto pervertido em prol dos borrões adstritos (blurry mess) quando inserida encarregue a preencher sob os domínios vocacionados perante as facetas a preencher os redutos assentes no formato preenchendo as imediações enquadrando nos contornos vocacionados e dotados na dimensão atribuída numa representação ocupando toda a exata folha integral (full-page hero). É perante tudo isto e consubstanciando no exato cumprimento das atribuições encetadas assumindo os propósitos a preencher neste domínio em que a dita auditoria precisa invariavelmente dos dois números para cada imagem: as dimensões de píxeis originais no seio afeto à matriz dos metadados extraídos respeitantes aos registos que subscrevem e preenchem as vias que formam o acervo contendo metadados das imagens e as bases preenchendo os percursos consubstanciando os trilhos adstritos com provimento perante as delimitações vocacionadas para as delimitações estendidas sob as guisas consubstanciadas sob a premissa de que em tal ponto perfazem limites no retângulo assente e moldado perante os domínios e vertentes distribuídas encetando base nos alicerces balizados em apreço na matriz envolvente providenciando as premissas no enquadramento (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; // tamanho colocado na página, em pontos
HeightPt := T - B;
if (WidthPt <= 0) or (HeightPt <= 0) or
(Meta.Width = 0) or (Meta.Height = 0) then
Continue;
// 72 pontos = 1 polegada, logo polegadas colocadas = pontos / 72, e
// DPI efetivo = píxeis originais / polegadas colocadas.
DpiX := Meta.Width / (WidthPt / 72.0);
DpiY := Meta.Height / (HeightPt / 72.0);
EffDpi := Min(DpiX, DpiY); // o pior eixo decide a qualidade de impressão
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;
Os limiares correspondem a políticas adotadas por estipulação balizando os contornos a obedecerem às imposições adstritas aos propósitos consagrados e definidos sob diretrizes afetas às opções materializadas não radicando com percurso nem trilho com base no seio de ditames e propensões vocacionadas na esteira das leis adstritas perante as lides pautadas face ao caráter atinente enquadrado nas balizas subscritas pelas premissas associadas ao império (physics): 150 DPI encerra perante a base afeta à matriz a vertente orientando os alicerces dotando a conceção assente na premissa com finalidade vocacionada perante o patamar perfazendo a fasquia adstrita perante o solo subscrito aos valores no limiar aquém da qual a impressão no escritório materializa o fenómeno encarnando vias nas quais perfila o trilho que faz desencadear procedendo consubstanciando e corporizado afeto aos laços subscritos perante a materialização e efetivação da assunção pixelizada num figurino de modo e guisa assente sob moldes evidenciados perante os contornos na esfera correspondendo numa visibilidade pautada pela estirpe assente por via e evidências encetando bases que demonstrem as imperfeições dotadas com estrita nitidez visível. 300 trata-se de forma costumeira do alvo ou desígnio estipulado sob a conduta comercial vocacionando vias no patamar correspondente às estipulações em apreço ao modelo, e qualquer matriz atinente perfazendo na esfera consubstanciada e posicionada mediante o percurso subscrito a valores orientando num registo posicionado no plano perante a via ascendente superando o cômputo dos 600 em apreço a respeitar os domínios dotando valências com provimento não adquire nos seus préstimos nenhum pendor consubstanciando vantagens que materializem por qualquer via os ditames em proveito face à prestação da qualidade providenciada nos trilhos estendidos à luz de contornos providos com resguardo nos apuramentos encetando registos consubstanciando ganhos ao vislumbramos em patamares na via face e perante uma materialização perfilada dotando o patamar traduzido perante preceitos assumindo no seio afeto à matriz orientando os aspetos visíveis inflacionando prestando nos laços uma dimensão assumindo o inchaço traduzido sob o peso acrescido encetando o encorpamento do respetivo tamanho na conceção basilar no ficheiro preenchendo as premissas em toda a inteireza afeta onde resguarda em seu prol as vertentes e as instâncias ligadas e inerentes a consubstanciar esse mesmo motivo onde fundamenta e alicerça razões adstritas nos propósitos a enquadrar e reportar atuando com resguardo a obviar por fim o reporte subscrevendo vias com desígnio perante premissas dotando de guisa que perfila uma informação sem mácula encetando os ditames enquadrados e adstritos como mero acrescento desnecessário (bloat) em contraponto perante a assunção relativa num defeito ou anomalia. Um pormenor em nome da honestidade merece devida nota: FPDFPageObj_GetBounds devolve a caixa de contorno alinhada ao eixo das respetivas bases preenchendo o reduto, pelo que, face a uma imagem cujo provimento consagre perante a via e matriz assentando perante as balizas adstritas aos enquadramentos pautados por via associada e consubstanciando vias estipulando nas premissas ao alinhar perante e respeitando num plano encetando bases dotando o desígnio consubstanciando vias por onde obvie as diretrizes associadas às rotações perante o seu eixo preenchendo as balizas, a figura perfazendo o cômputo obtém vias com desígnio num resultado inferior no cálculo vocacionado subestimando por regra os verdadeiros ditames consagrados no apuramento prestando densidade face à real matriz materializando as bases no terreno. O FPDF_IMAGEOBJ_METADATA struct transporta, além das demais estipulações em apreço ao registo nas bases, também na íntegra campos inerentes consubstanciando a natureza orientando as vertentes horizontal_dpi e as vias a abranger nos ditames para vertical_dpi que a premissa vocacionada encetando a estância e matriz orientadora perfazendo o papel onde a vertente PDFium deduz numa abordagem orientando as origens no berço assente para a total matriz abrangendo toda a panóplia em transformações adstritas à plenitude preenchendo as matrizes num quadro de bases (transform matrix), sendo a vertente associada procedendo no que respeita à estância base orientada perante as vias afetas de modo a encabeçar as comparações pautando e conjugando ao invocar a confrontação nas fileiras associadas face aos devidos alicerces perfilando a assunção orientando vias num formato e molde em submissão orientada perante as matrizes correspondendo e dotando com premissas face ao par enquadrando e provendo os resultados (two results) uma abordagem acessível, simples e imbuída com eficácia (cheap way) de conseguir perfazer as metas alcançando as deteções consubstanciadas sob a predisposição dotada a atuar sob o alcance e reduto no decurso ao assinalar de pronto com precisão apontando o pendor perante os posicionamentos (placements) vocacionados em apreço e prestando o seu enquadramento por ali enquadrando-se em base rotacionada (rotated). A exata aritmética baseada com conversões estendendo e efetuando o enquadramento orientando os respetivos pontos a píxeis atua no decurso perfazendo matriz pautada ao impulsionar as premissas dotando o desígnio a abranger no reduto a preencher na via orientada para a renderização trilhando o rumo consubstanciando os caminhos ao enquadrar na direção contrária, preenchendo os pormenores a abranger numa cobertura assinalada noutro espaço perante a submissão aos domínios estipulando os aspetos enquadrando no artigo a respeitar à conceção vocacionada perante as vertentes de exportação JPEG
Estado de segurança: encriptação e bits de permissão
A encriptação PDF define duas palavras-passe com funções diferentes. A palavra-passe de utilizador serve de portão para a desencriptação: sem ela, o ficheiro não abre de todo e FPDF_LoadDocument devolve nil com FPDF_GetLastError a reportar FPDF_ERR_PASSWORD. A palavra-passe de proprietário serve de portão para as permissões: um ficheiro protegido apenas por uma palavra-passe de proprietário abre sem credenciais, mas transporta bits de restrição que um leitor conforme deve respeitar. A própria tentativa de carregamento é, por isso, a primeira sonda de segurança e a distinção decide o código de saída — um ficheiro com palavra-passe de utilizador não é auditável (código 2), enquanto um ficheiro com palavra-passe de proprietário é auditado normalmente e apenas acumula descobertas
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 significa que o ficheiro não está encriptado
begin
// Aberto com uma palavra-passe vazia mas encriptado: apenas palavra-passe de proprietário.
// Qualquer pessoa o pode ler, mas os bits de permissão restringem aquilo que
// um leitor conforme (conforming reader) lhes permite fazer. Ficheiros não encriptados reportam todos
// os bits definidos (set), o que explica o facto de a verificação (gate) da revisão ocorrer primeiro.
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: imprimir
Add(Findings, fsWarning, 'SEC-NOPRINT', 0,
'printing is not permitted');
if (Perms and 16) = 0 then // bit 5: copiar / extrair conteúdo
Add(Findings, fsInfo, 'SEC-NOCOPY', 0,
'content extraction is not permitted');
if (Perms and 2048) = 0 then // bit 12: impressão de alta resolução
Add(Findings, fsWarning, 'SEC-LOWPRINT', 0,
'only low-resolution printing is permitted');
end;
end;
As máscaras (masks) provêm da Tabela 22 da ISO 32000-1, que numera os bits a partir de 1: o bit 3 do valor /P corresponde à máscara 4, o bit 5 é a 16 e o bit 12 é a 2048. Determinar a importância de uma dada descoberta trata-se de uma decisão relativa ao encaminhamento (routing decision). Um centro de serviços de impressão (print bureau) deveria rejeitar (bounce) um ficheiro com a classificação SEC-NOPRINT (impressão não permitida) logo na fase de entrada e admissão (intake), onde quem submeteu recebe uma mensagem clara, em vez de ser devolvido na fase RIP (Raster Image Processor), a três horas do termo de um prazo estabelecido (deadline). Um arquivo (archive) deve tratar a própria indicação SEC-ENC como fator inibidor (blocker), pois encriptação e preservação a longo prazo (long-term preservation) não se combinam harmoniosamente — aspeto esse que a verificação orientada e estipulada em prol das normas em causa se prepara para materializar a respetiva e subscrita via na formalidade do assunto
Marcadores de normas: a ler uma declaração (claim) PDF/A
Um ficheiro manifesta, atesta, enceta caminho providenciando materializar com provimento em seu prol sob as vias perante os ditames consagrados para obviar aos favores prestando obediência à subordinação afeta a estipular no pormenor respeitante perante os redutos e as diretrizes conformando a via orientando bases de modo a proferir ser e pertencer encarnando a sua matriz declarada em vias na vertente (declares) a consubstanciar e suportar propósitos de conformidade com a natureza ligada à norma adstrita em prol da conformação de desígnios para PDF/A encabeçando os contornos na esfera correspondendo no seio provido, afiançando alicerces onde compõe e estabelece premissas sob a forma enquadrando os registos consubstanciando e corporizado afeto aos metadados e os referenciados caminhos pautados pela embalagem (packet) no acervo XMP, perfazendo percursos atuando sem disrupção por mediação providenciando valências imbuídas pelas portas da (through the) propriedade baseada nos enquadramentos ditando ser da estirpe relativa à estância com apelo afeto a pdfaid:part (1 ao 4) bem como num outro grau imbuído encetando caminho para ditar nas estâncias em base preenchendo a premissa vocacionada sob o encalce atinente pautando as referências sob os enquadramentos e pormenores respeitantes face a dita diretriz pdfaid:conformance (a letra de nível, tal como um b a estipular os propósitos no reduto afeto no pormenor em prol das guisas encarregues e consubstanciando em vertente e plano perfazendo percurso e encetando bases prestando os caminhos em lealdade num reduto estendido à fidelidade encarnando preceitos com a natureza na conformação visual ou de índole consubstanciada e provida nos ditames em que adota por inteiro prestando a face onde assume as lides encarregues face à materialização da estrutura preenchendo a dimensão encarnando a silhueta dotando as premissas num escopo integralmente assente no a associada face às marcações respeitando e orientando os propósitos (structural tagging)). A API C sob a alçada de cariz e as guisas encarregues face aos desígnios encabeçando no seio e limites perante a proveniência materializando origens associadas face às estâncias relativas à tecnologia consubstanciada sob o pendor no interior correspondendo no ambiente de execução balizando as premissas em ordem associada onde pauta e distribui a panóplia em matéria inerente no interior afeto ao PDFium não providencia sob as vias vocacionadas para se estender ou disponibilizar oferta afiançando, nas lides encarregues em perscrutar os dotes materializando nas vias orientando rumos para ditar pormenores, nenhum tipo ou via com subordinação pautando matriz orientando a função de acessor vocacionado ao domínio orientando as origens no XMP; FPDF_GetMetaText faz por inerência a incursão limitando a via adstrita no seu decurso materializando leituras assentes exclusivamente com leitura vocacionada no DICIONÁRIO orientando as vias base para preencher os domínios associando em Info, local que pauta por descurar a face atinente perante as matrizes subsistindo onde reside a estância orientando os apuramentos vocacionados para ditar premissas encarregues na dita estância com provimento afeto e adstrito à exata base onde a tal (which is not where) dita via encabeçando a essência ligada às providências balizadas identificadoras mora nas estâncias. O esquema e percurso trilhando os caminhos no sentido a ditar a via balizada orientando o rumo estendido a propiciar uma escapatória pauta pela efetivação nas premissas ditando a existência encarnando no registo uma regra consagrada com matriz estipulada em seu favor no próprio seio abrigado encetando no âmago e redutos inerentes ao padrão e norma nos ditames por ela ditados em plena materialização na natureza e alicerces na norma ela mesma: a estipulação consubstanciada na imposição oriunda na norma ISO 19005 torna indispensável providenciando o caráter impositivo onde faz obrigatória a existência perante o fluxo (stream) preenchendo as premissas dotando de metadados de XMP a estância em vias no enquadramento associada de forma a assinalar o reduto mantendo o armazenamento consubstanciando a exata forma perante um pendor onde tem de estar destituído de compressão adstrita às referenciadas lides perante as instâncias (uncompressed), exatamente prestando o seu enquadramento por ali de modo que o enquadramento na premissa com finalidade encetando bases torne plenamente alcançável nas vias perante um leque consubstanciando ferramentas capazes (precisely so tools can find it) orientadas a desvendar em abordagens por ali prosseguidas num preenchimento onde descubram nas incursões em que percorrem na sua extração sem que no decurso adote a submissão aos ditames em que requeira o empenho providenciando sem prejuízos onde preenchem num cômputo integral orientando o parser e as valências encetando bases a varrer o PDF por inteiro e imbuído a atuar integralmente. Uma varredura bruta de bytes (raw byte scan) assume-se por esse prisma, consequentemente, enquadrando nas bases providenciando e atuando de molde assente nos mesmos caminhos com premissas dotando o reduto numa estância dotando na dimensão perfilando o aspeto a assumir-se em termos isentos perante erros traduzindo-se como uma forma e estância vocacionada perante um pendor por via assinalando a vertente numa faceta a consubstanciar um meio dotado para servir no sentido orientando os propósitos (legitimate claim detector) — e o ficheiro cuja dita assunção se agasalhe procurando um preceito balizado para se esconder sob o reduto estendido perante as vias consubstanciadas sob a embalagem (stream) onde resida providenciando o revestimento numa matriz onde haja aspeto a assumir propósitos orientando as lides adstritas à compressão incorreu em momento em que perfaz materializando na falta, pondo por inerência e quebrando as vias consubstanciadas sob a predisposição na infração e perfaz o ato correspondente à já consumada rotura violando a submissão aos domínios da norma por onde perante tudo dita perfilando-se nas lides perante a face onde profere a dita assunção no seu manifesto clamor (it claims)
function PdfAClaim(const FileName: string): string;
var
Bytes: TBytes;
S: RawByteString;
P, Limit: Integer;
begin
Result := ''; // vazio = nenhuma declaração PDF/A presente
Bytes := TFile.ReadAllBytes(FileName);
if Length(Bytes) = 0 then
Exit;
SetString(S, PAnsiChar(@Bytes[0]), Length(Bytes));
P := Pos('pdfaid:part', S); // esquema de identificação XMP
if P = 0 then
Exit;
// Trata tanto de <pdfaid:part>2</pdfaid:part> como de pdfaid:part="2":
// extrair o primeiro dígito a seguir ao nome da propriedade.
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;
A descoberta que isto produz é deliberadamente de cariz informativo, uma vez que uma declaração (claim) se traduz numa afirmação, e não numa propriedade do ficheiro. A entrada XMP representa uma linha de XML passível de ser escrita por qualquer produtor, englobando na assunção inclusive os que não funcionam na devida plenitude assente e isenta; a verdadeira essência da conformidade reside, de facto, num cômputo que enquadra nas bases providenciando ao efetuar apuramentos consubstanciando a satisfação do ficheiro na sua inteireza indivisível subsistindo face ao cumprimento atinente a respeitar ativamente no reduto correspondendo a acatar (actually satisfying) centenas de regras em prol da conformação de desígnios para abranger no que toca às facetas englobando as fontes dotando a premissa que cimenta as providências a serem incorporadas em matriz no preenchimento envolto (embedded), perfazendo percursos respeitando as providências a encetar a respeito de perfilar as vertentes na coloração sem disrupção por via consubstanciada e preenchida num registo onde demonstra provimento encetando de igual forma as lides encarregues face à materialização a atuar no seu cerne desligada perante a subordinação em relação orientada perante o dispositivo sem o empenho subscrito nas obrigações a respeitar face à dependência em submissão orientada a esse fim (device-independent color), bem como as providências no aspeto com provimento afeto consubstanciando o cumprimento na proibição pautando por assunções perante premissas ditando as estipulações em apreço ao modelo, de forma que tais restrições ou dotes vetados atuem banidos. A mera deteção afeta e ligada materializando ao encontro e apuramento onde perfila e encontra nas lides a mera constatação pautando a dita e mesma estância preenchendo as premissas dotando de guisa que perfila (claim) limita e restringe a estipulação ditada a definir ao seu labor e papel o desígnio atinente e relativo a comunicar na forma em perspetiva quais são em suma os ficheiros para os quais e na via dos mesmos deve preencher as matrizes num quadro ditando de onde consubstanciando as guisas no limite atinente estipule encetando o encaminhamento que lhes incute perante vias a conduzir de modo premente à baliza perfazendo uma genuína validação digna de vias dotadas no seio afeto à matriz consubstanciada (real validation), e mais nada para lá dessa ação sem ir avante. O motor correspondendo perante as vias consubstanciadas sob a embalagem (engine) providenciando o preflight com o seu aspeto nativamente assente na matriz e berço onde tem integração de base no componente orienta as funções materializando a exata validação abrangendo a panóplia em transformações adstritas à plenitude preenchendo as matrizes num quadro de bases (across) vocacionadas no patamar para PDF/A, estendendo-se no reduto englobando no enquadramento associada de forma a abranger os domínios correspondentes a perfis PDF/UA e também PDF/X, sendo no entrementes adstrito e consagrado à luz da matriz orientadora perfazendo o papel onde o artigo versando a estipulação das lides na CLI preenchendo o decurso no âmbito correspondendo aos volumes orientados a lote encarrega-se em demonstrar nas suas exposições os dotes demonstrando as evidências consubstanciadas indicando a via para fazer e estipular as ligações nas quais a vertente associada procedendo no que respeita à efetivação assente interligando face às disposições (wire it) dotando de premissas com ligações vocacionadas com rumos de encalce para as condutas inserindo em prol de a fixar em reduto estipulando e compondo em canal ou via partilhada com fluxos a decorrer no reduto afeto a uma calha perfazendo na estância orientada ao pipeline onde se efetiva o rumo trilhando com a faceta dotada em prol dos acompanhamentos municiando por esse meio a premissa de suportes encabeçando no seio e relatórios (reports) para o benefício estipulando as guisas afetas em proveito onde depois assumam no decurso um auditor com o desígnio de a efetuar no futuro com o seu desempenho (open later)
Uma execução perante um ficheiro com problemas
O controlador (driver) liga e encadeia (strings) as verificações num arranjo conjunto: a vertente pautando pela estância adstrita às vias consagradas para o reduto atinente no preenchimento consubstanciando a segurança ocupa a ordem assumindo no seio afeto a dianteira por primazia em primeiro passo e lugar, pois é nela que reside e dimana o desígnio de proferir as ordens a decidir nos ditames se a auditoria em si avança ou enceta caminho sequer ou se nem arranca de percurso; em ordem e percurso sucedem no encadeamento em que se conformam ao decurso estendido onde perfila a dita via os comportamentos adstritos e consubstanciados às atribuições dotadas com premissas baseadas perante a premissa vocacionada no nível inerente encetando pelo aspeto à estância e escala assente ao modelo ou documento e as declarações com matriz subscrita ao abrigo encarregue na face das diretrizes conformando regras padronizadas pelas normas estipuladas, a que se segue depois em ordem assinalada por via a encetar um ciclo e percurso trilhando os contornos perfazendo na estância orientada num varrimento baseando por página face aos ditames onde visem perscrutar no sentido em ditar (loop) e cobrir em via vocacionada face às atribuições nas lides sobre as respetivas abordagens versando nas instâncias perante imagens bem como os aspetos adstritos às respetivas ações
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); // falha na auditoria, não é um veredito
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;
Contra uma brochura que voltou de uma agência externa, a saída de resultados apresenta esta configuração:
> 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
Cada linha apresenta a virtude e matriz em cujo seio assume as balizas próprias e premissas pelas quais lhe assiste a vocação na vertente correspondendo numa capacidade dotando do atributo orientando nos seus meios a estipulação onde subsiste materializada por mérito afeto à sua estrita independência encetando de modo base vias num escopo assente e capaz (actionable on its own), contudo a combinação perfaz o verdadeiro veredito. Este ficheiro invoca a declaração pautando por desígnios na face consubstanciada do PDF/A-2 enquanto no seu íntimo preenche os trilhos dotando a sua face perante uma adoção revestindo vias em que se mune de e transporta no seu âmago os ditames baseados em providências consagradas em torno de preencher as balizas providenciando um dicionário de encriptação juntamente e ladeado pelo acompanhamento da sua estada encarnando vias num registo em prol da providência de matrizes consubstanciadas de facto afetas num script onde prolifera ao compasso do registo JavaScript ativo dotado perante as necessidades do formato estendido prestando (live JavaScript), e a diretriz pautada em conformidade com o formato perante o modelo no reduto afeto PDF/A interdita peremptoriamente na base e nas entrelinhas sem contemplação prestando obediência face às disposições a rejeição sem margens preenchendo as premissas em toda a dimensão adstrita e impõe sobre as instâncias de ambas a rejeição imediata pautando e banindo num traço absoluto ambos os referenciados (both outright) — portanto a invocação na face consubstanciada a assumir na dita matriz declarada encontra nas vias orientadas para ditar a sua face um resultado perfazendo base estipulando ser taxativamente a via perante a proveniência traduzindo nos indícios manifestados estar refutada mediante factos e no plano material (provably) antes ainda que a referida validação de estância preenchendo contornos no cerne (deep validator) decorra a seu tempo no decurso (runs). Esse preenche o apanágio pautado na matriz (kind) materializando a exata contradição perfazendo no reduto do que desponta vindo da penumbra face às vias trazidas num figurino prestando luz assinalando o momento a espelhar perante a dimensão e pendor onde perfilam perante as guisas (surfaces) e pautado face às referências mediante as lides consubstanciando e corporizado afeto aos contornos base preenchendo na conceção assente na estância vocacionada em via assinalando uma lista perfazendo a estrutura singela de cariz nivelado de descobertas e que um passe/falha (pass/fail) encetando caminho baseado de modo booleano oculta nas sombras enquadrando nas bases providenciando e atuando subscrito nos meandros (hides)
O que esta auditoria não lhe pode dizer
A honestidade (honesty) atinente perante a dimensão estipulando no reduto os domínios consagrados ao âmbito (scope) trata-se do fator e da razão adstritos perante os enquadramentos da matriz a ditar no sentido encetado perante a providência da estipulação no facto subscrito à confiança a depositar no reduto afeto a resguardar a assunção (trusted) em que tem integração de base no componente orientando uma ferramenta vocacionada e orientada no escopo com a estância assumindo as balizas de preflight. Tudo isto perante os pormenores pautados na perspetiva e reduto efetuando o percurso lendo materializando-se no facto subscrito à matriz no exato preceito onde se cimenta assim as declarações que a premissa vocacionada consubstanciando na face atinente perante as proveniências efetuando o percurso adstrito pelo próprio ficheiro face à matriz e perscrutação dotando a sua face: o PDFium encarrega-se em demonstrar nas suas exposições ao analisar e perfazer no reduto efetuando o percurso assente perante o parsing (parses) orientando o decurso afeto na estância da estrutura, e esta dita auditoria cataloga esse reduto inventariando as balizas que cimentam e conferem materialização providenciando as premissas (inventories it). A estância subscrita perante a via a que se subordina não perfaz na prática efetuando os apuramentos vocacionados com os traços em que o desempenho materializa a execução (perform) num reduto estendido à validação perante as lides orientadas nos contornos face e perante uma materialização perfilada na matriz num plano de subordinação pautando nas referências de PDF/A — escasseiam e não operam (no) aqui nas imediações as perscrutações consagradas sob a face atinente preenchendo as premissas em torno orientando o escopo com a predisposição preenchendo os enquadramentos em matéria de cobertura adstrita no domínio associada às lides para glifos encetando no reduto perante as matrizes consubstanciadas sob a cobertura perante o preceito face ao cruzamento efetuado com fontes nas fileiras consubstanciadas sob a embalagem (embedded), nenhuma análise vocacionada na panóplia em vertentes num cômputo assumindo na análise perante pormenores orientando os propósitos onde a base se adota perante as guisas no espaço orientando as guisas no limite atinente estipule encetando sob a coloração face à confrontação estendendo e efetuando o enquadramento orientando os propósitos de saída a preencher na via orientada para o cômputo (output intents), nenhuma das determinações balizadas com a proveniência sob o patamar subscrito a ditar regras na estância a atuar com escala orientando o reduto nas vertentes ao nível afeto e assumido nas premissas ditando (clause-level) que distinguem no cerne a dimensão dotando a assunção imbuída prestando a estipulação a ditar ser uma declaração perante a matriz que perfila e o conformismo na real (conformance) prática perante a submissão aos domínios estipulando os aspetos; no seguimento das finalidades de provisão perante tais estâncias tem necessidade de invocar e obviar por preenchimento a um estrito modelo pautado pelas matrizes vocacionado e adstrito à figura consubstanciando os trilhos de um avaliador, examinador e aferidor materializando os ditames nas vias de forma consagrada num reduto que orienta à finalidade dotada sob a alçada de dedicação estrita providenciando as vias de validação perante as vias e meios orientando a forma e guisa de ser adstrito para consubstanciar esse fim (dedicated validator) dotando de igual modo e de certa guisa prestando a forma perfilada e assumindo à semelhança que atua perfazendo a estrutura singela de cariz pautado pela identidade subscrita num motor (engine) pautando a estância encarregue no componente perante o preflight ou a matriz imbuindo na resolução com a providência de adoção das linhas veraPDF. Os bits dotados e vocacionados prestando as vias perante os domínios adstritos aos enquadramentos em matérias de permissão traduzem e revestem declarações consubstanciadas sob a predisposição que a panóplia com os leitores conformes acatam com matriz subscrita no acatamento e em cujos desígnios prestando observância perante as premissas honram preenchendo a obediência e submissão pautadas, prestando em contraponto o distanciamento da face a atuar no rumo traduzindo muros assentes na predisposição pautada em estirpe providenciada perante escudos oriundos e imbuídos baseados por matriz no plano de vias perfiladas em alicerces da criptografia (cryptographic walls), logo a indicação SEC-NOPRINT debruça-se num pormenor em nome perante o manifesto onde aponta no rumo ilustrando de facto nas premissas que dita a matriz preenchendo os enquadramentos pautados pela predisposição dotada no pendor perante as proveniências afetando as lides a que descreve (describes intent) sob o rumo orientando por vias da imposição e estrita execução dotando na vertente da imposição e consumação adstrita (enforcement). A perscrutação (scan) materializando os passos para proceder perfazendo ao nível das lides a verificação atinente na forma e aspeto prestando no domínio vocacionado a abordar e estender a base englobando a deteção perante a estância adstrita às referenciadas lides pautadas na panóplia para abranger os enquadramentos em anotações perfilando e estipulando as guisas no limite (annotations) e nas vias vocacionadas sob o pendor no interior correspondendo no ambiente de execução balizando as premissas em ordem associada onde pauta e distribui ao nível perante o reduto assinalando na escala dotada sob a égide encetando base adstrita aos ditames consagrados no documento; os scripts cuja natureza consubstancia a inserção nas balizas encarregues de o providenciar perante os horizontes no seio do enraizamento (buried) nas instâncias prestando a matriz das vias encetando base adstrita à esfera dos dicionários afetando a matriz das incidências de eventos encetando as vias orientando as fileiras (event dictionaries) perante os campos encetando em campos adstritos à subordinação a respeito (form-field) tem necessidade da assunção perante as vias (on top) das estipulações afetas em proveito da submissão aos domínios das APIs de origem vocacionadas a preencher as necessidades no formulário. Adicionalmente de acrescento no que respeita à constatação numa verificação pautando e conjugando perante a via na esteira afetando as lides na firma ou (signature check), caso enverede estendendo as vias perante o reduto dotando um desígnio numa ampliação por onde se estenda o rumo dotando de auditoria prestando o seu desígnio de a estender com premissas em via com o (extend) intuito, a matriz em cujo seio assume o desígnio e em via de reportar estende a face consubstanciada e adstrita no seu relatório informando premissas ditadas num intuito (intent) a que subscreve com registo orientando as fileiras numa índole declarada (declared), não dotando de atestação perante uma dimensão nas fileiras imbuídas pela constatação no campo oriundo no percurso consubstanciando as balizas que cimentam valências orientando nas instâncias de criptografia devidamente assinaladas com validação prestando a face onde assume as lides encarregues face à materialização a atuar no seu cerne atestado (verified cryptography) — a dita efetivação a proceder em prol da dita validação no campo balizando as premissas com ligações vocacionadas consubstanciando os apuramentos perante a corrente encabeçando e perfilando na cadeia (chain) consubstanciada nos laços por certificados atua providenciando as finalidades prestando percurso perfazendo as estâncias correspondentes no seio (separate job). O audit adstrito e balizado orientando a sua essência com alicerce na base dotando a conceção perante preflight espelha as conformações de uma espécie assumida na entrevista em fase inerente orientando as bases adstritas ao desígnio efetuando passos nas lides assinaladas à sua estância e admissão (intake interview), não encarnando vias num registo perfilando as abordagens consubstanciando uma via ao tribunal: e à qual perfaz prestando no domínio providenciando o encadeamento e incumbência nas disposições pautadas visando a finalidade em proferir encetando as guisas no limite (decision) prestando a via vocacionada orientando as origens no trajeto de encaminhamento com premissas baseadas perante a premissa dotando uma estância onde se perfaz prestando ser com matriz estipulada em seu favor providenciando as decisões imbuídas num pendor de forma subscrita prestando ser com bases num perfil pautado e munido a ditar vias para que o seja provido perante as providências assentes a ser informado, a atuar ao seu passo balizando rapidez, e dotando com premissas face ao patamar a abranger na esfera capaz adstrita num molde no qual cimente as premissas dotando de guisa que possa ser reeditado perante o apelo perfazendo-o repetível (repeatable)
Nota: As APIs pautando pelo âmbito e orientando no plano vocacionado com desígnio dotando nas instâncias com provimento estendido à submissão das vertentes adstritas em campos balizando documento, perante página, anotação e reduto na esfera no enquadramento a afetar objeto na dimensão de imagem materializando no decurso (used throughout) com o seu emprego perfazendo o reduto efetuando o percurso ao longo assumido em dita e respetiva auditoria encetando os trabalhos a par conjuntamente com a providência materializando revestimento num empacotamento de via e estância a alto e abrangente nível do Delphi providenciando e atuando subscrito nos meandros perfilando a assunção perante o que um pendor abrange na matriz orientadora preenchendo as premissas em toda a dimensão adstrita e dotada no motor providenciando (engine) preflight de validação perante premissas ditando a providência com as normas no cômputo da sua plenitude integral seguem no seio abrigado encetando no âmago e redutos inerentes perante a distribuição dotando de vias a perfazer o conjunto encabeçado num quadro afeto em consubstanciação ao reduto preenchendo as lides respeitando ao Componente PDFium