Salta ai contenuti

Inspect: introspezione e preflight dei PDF

Il modulo Inspect legge un PDF esistente e ne descrive il contenuto: punteggio di complessità, audit di font e immagini, indizi di conformità e flag di rischio. Una policy di preflight trasforma il report in una decisione di pass/fail, permettendo di filtrare un documento prima che entri in una pipeline.

Stabilità: sperimentale. L’introspezione è una superficie in evoluzione. La forma di InspectResult, l’insieme dei flag di rischio e il percorso opzionale di ispezione accelerata possono cambiare tra versioni minori. Usarlo per diagnosi e filtraggio; non basare ancora contratti di lunga durata sulla forma del risultato.

Terminal window
composer require nextpdf/core:^3

Inspector è il punto di ingresso. Implementa InspectorInterface ed espone un solo metodo: inspect(string $pdfData, InspectConfig $config = new InspectConfig()): InspectResult. È di sola lettura: analizza un PDF e lo caratterizza, senza modificare il documento.

InspectResult è il report strutturato. Include il punteggio di complessità, gli audit, gli indizi e un insieme di RiskFlag. Risponde a hasRisks() / hasRisk(RiskFlag $flag) per permettere al chiamante di gestire un rischio specifico, invece di analizzare testo libero. ComplexityScore espone un punteggio numerico e una fascia category(). FontAuditEntry e ImageAuditEntry descrivono le risorse incorporate. ComplianceHint segnala probabili problemi di conformità. InspectIssue registra un rilievo puntuale. InspectDepth sceglie quanto a fondo spingersi con l’ispezione, e toSpectrumDepth() mappa questa scelta sul percorso accelerato quando il sidecar Spectrum è disponibile. L’ispezione funziona anche senza il sidecar. Il sidecar incide solo sulle prestazioni, non sul contratto. InspectResponseParser costruisce un InspectResult a partire da una risposta grezza (per esempio quella del percorso accelerato) con un trace id opzionale.

PreflightPolicy è il livello decisionale. evaluate(InspectResult $result) applica una policy configurata a un risultato e restituisce l’esito della policy. L’intero modulo è disponibile da @since 2.2.0.

TipoMembri principaliRuolo
Inspectorinspect(string $pdfData, InspectConfig $config): InspectResultIspettore PDF di sola lettura (@since 2.2.0)
InspectResulthasRisks(), hasRisk(RiskFlag), accessor score/auditReport di ispezione strutturato (@since 2.2.0)
ComplexityScorecategory()Punteggio numerico di complessità e fascia (@since 2.2.0)
FontAuditEntry / ImageAuditEntryaccessor delle risorseAudit delle risorse incorporate (@since 2.2.0)
ComplianceHint / InspectIssueaccessor dei rilieviIndizi di conformità e rilievi (@since 2.2.0)
InspectDepth (enum)toSpectrumDepth()Profondità di ispezione → percorso accelerato (@since 2.2.0)
PreflightPolicyevaluate(InspectResult): array, toArray()Decisione di preflight pass/fail (@since 2.2.0)
InspectResponseParserparse(array, InspectConfig, ?string $traceId): InspectResultCostruisce un risultato da una risposta grezza (@since 2.2.0)

Per la tabella PHPDoc completa, eseguire composer docs:generate-api-php -- --module=Inspect.

Sorgente: examples/34-inspect-layout-boxes.php dimostra come leggere la geometria di pagina. Per ispezionare il profilo di rischio di un PDF arbitrario:

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Inspect\Inspector;
$result = (new Inspector())->inspect(file_get_contents('/srv/in/incoming.pdf'));
if ($result->hasRisks()) {
echo "Complexity: {$result->complexityScore()->category()}; risks present.\n";
}

Filtrare un PDF in ingresso tramite una policy di preflight e rifiutarlo in presenza di qualsiasi rischio.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Inspect\Inspector;
use NextPDF\Inspect\PreflightPolicy;
use Psr\Log\LoggerInterface;
final readonly class IngestPreflight
{
public function __construct(
private Inspector $inspector,
private PreflightPolicy $policy,
private LoggerInterface $logger,
) {}
public function accept(string $pdfData): bool
{
$result = $this->inspector->inspect($pdfData);
$verdict = $this->policy->evaluate($result);
if ($verdict !== []) {
$this->logger->warning('PDF rejected at preflight.', ['findings' => $verdict]);
return false;
}
return true;
}
}
  • inspect() è di sola lettura. Non modifica né ripara mai l’input; non aspettarsi che restituisca un documento «corretto».
  • hasRisk(RiskFlag) è il controllo puntuale. Ramificare solo su hasRisks() tratta ogni rischio in modo identico — di solito serve un flag specifico.
  • InspectDepth controlla il costo. Un’ispezione profonda di un PDF grande è notevolmente più lenta; scegliere la profondità minima necessaria per rispondere alla domanda.
  • Il percorso accelerato di Spectrum cambia le prestazioni, non il contratto del risultato. Basare il codice su InspectResult, non sulla forma della risposta accelerata.
  • PreflightPolicy::evaluate() restituisce i rilievi; non solleva eccezioni. Un risultato vuoto equivale a un pass — agire in base al valore restituito.

Il costo dell’ispezione cresce con la dimensione del documento e con la InspectDepth scelta. L’ispezione superficiale è veloce; un audit profondo di un PDF grande può avvicinarsi al budget. Il percorso Spectrum delega il parsing più oneroso quando è disponibile. Il performance_budget di 1500 ms wall / 64 MB di picco è il carico di lavoro di riferimento. Il profilo di riproducibilità è structural: un risultato può trasportare un trace id e una temporizzazione. Due esecuzioni possono differire in quei campi, mentre i rilievi rimangono stabili per lo stesso input.

Inspector::inspect() analizza byte PDF non attendibili: è precisamente il suo scopo, quindi trattare l’input come ostile. Per i documenti forniti dagli utenti, eseguire l’ispezione in un worker vincolato e limitare a monte la dimensione dell’input. Un PDF deliberatamente complesso è un vettore di denial-of-service a prescindere dalla profondità. Il risultato descrive il documento, ma non lo sanifica: un verdetto di «basso rischio» è un’euristica, non una garanzia di sicurezza. Trattare come non attendibili le stringhe e i metadati estratti. Vedere il modello di minaccia del motore in /modules/core/security/.

Questo modulo riporta indizi di conformità; non costituisce il verdetto di conformità autorevole. ComplianceHint segnala probabili problemi in modo euristico. Il verdetto di conformità autorevole per PDF/A, PDF/UA e ISO 32000-2 proviene dai validatori di riferimento guidati da /modules/core/cli/ e dalle suite oracle e golden descritte in /modules/core/conformance/. Non trattare un risultato Inspect pulito come una certificazione di conformità.