跳转到内容

Compliance(合规):PDF/R-1 验证器、Arlington 语法和生命周期工具

NextPDF\Compliance 提供字节流验证器和一套语法交叉检查,会读取一份完成的 PDF,并报告它在何处偏离规范性契约。验证器返回零个发现项,只表示针对它已实现的条款得到 已检查 的结果,并不等同于一份全面的合格证明。

Terminal window
composer require nextpdf/core:^3

这个模块分为三个部分。

PdfRValidator 验证一份候选的 ISO 23504-1:2020(PDF/R-1)字节流。它作用于原始字节,而不是 writer 的内部状态。它会识别 writer 计划输出的内容与规范要求之间的偏离。它是最后一道检查。已实现的条款集为 v5.1.0 集合:§5 版本识别注释、§6.2.2/§6.2.3 标头允许列表、§6.2.4 generation-0 与对象流禁用、§6.5.7 内容流运算符允许列表(仅限 qQcmDo)、§6.6.1 图像 XObject 键值允许列表、§6.4.3 Info 字典键值允许列表,以及 §6.3 Catalog 键值允许列表。§6.7 增量更新与 §6.8 加密在初始集合中明确排除于范围之外,并已在 claims.json 中声明。验证器不会在遇到第一个发现项时就抛出异常。它会在一次遍历中收集每一处偏离,让调用方看到完整差异。

PdfRConformancePolicy 是一个不可变策略,用于 PDF/R-1 周边那些 建议但仅供参考 的范围。规范性 §6 基线始终不可配置。该策略只控制 §A.5 实现限制建议、§6.6.1 多重区块(multi-strip)的不建议用法,以及下游 PDF/A 重新分类所需的 §A.6 XMP 要求。

ArlingtonValidator 以仅报告模式驱动上游 PDF Association 的 Arlington PDF 模型。在当前周期中,它始终仅供参考:validateReportOnly() 永远不会抛出异常。它会在三种模式之间降级。当参考检查器(reference checker)二进制文件存在时,它会解析结构化的发现项。当只有固定语法时,它会输出一个 info 发现项,以证明固定语法已加载。当语法不存在时,它会返回一个空列表。WaiverRegistry 让编排器(orchestrator)在保留审计轨迹的同时,抑制已知可接受的差异。

这条诚实原则与 CSS 支持矩阵和一致性(conformance)模块保持一致。只有当存在通过的测试且引用了规范性条款时,某个条款才会标记为 Verified(已验证)。已实现但缺少专用通过 fixture 的条款则标记为 Claimed(已声明)。范围外的条款会明确说明,而不是留下模糊空间。发现项为零的 PdfRValidator 结果只断言它实际检查过的条款。它对 §6.7 或 §6.8 不做任何声明,因为它没有实现这两节。

类型种类主要成员
NextPDF\Compliance\Validator\PdfRValidatorfinal classvalidate(string $pdfBytes): list<PdfRValidationFinding>
NextPDF\Compliance\Validator\PdfRValidationFindingfinal readonly classstring $clause(条款)、'error'|'warning'|'info' $severity, string $message(消息属性)
NextPDF\Compliance\Profile\PdfRConformancePolicyfinal readonly class__construct(bool $enforceA5ImplementationLimits = true, bool $rejectMultiStripPages = false, bool $requireXmpForA6Compatibility = false); lax(), strictArchival()
NextPDF\Compliance\Validator\ArlingtonValidatorfinal classvalidateReportOnly(string $pdfPath): list<ArlingtonFinding>
NextPDF\Compliance\Validator\WaiverRegistryfinal classisWaived(string $validator, string $ruleId, string $scopeKey): bool
<?php
declare(strict_types=1);
use NextPDF\Compliance\Validator\PdfRValidator;
$validator = new PdfRValidator();
$findings = $validator->validate(file_get_contents('candidate.pdf'));
if ($findings === []) {
// Zero divergences from the §6 clauses PdfRValidator implements.
// This is NOT a PDF/R-1 certificate — §6.7 and §6.8 are not checked.
echo "No PDF/R-1 §6 divergences detected (implemented clause set).\n";
} else {
foreach ($findings as $f) {
echo "[{$f->severity}] §{$f->clause}: {$f->message}\n";
}
}
<?php
declare(strict_types=1);
use NextPDF\Compliance\Validator\ArlingtonValidator;
use NextPDF\Compliance\Validator\ArlingtonGrammarLoader;
use NextPDF\Compliance\Validator\WaiverRegistry;
$validator = new ArlingtonValidator(
waivers: new WaiverRegistry(/* loaded waiver entries */),
grammar: new ArlingtonGrammarLoader(/* pinned submodule path */),
adapter: null, // grammar-only mode when the reference checker is absent
);
// Advisory by contract — never throws on findings.
$findings = $validator->validateReportOnly('artifact.pdf');
foreach ($findings as $finding) {
// Each finding pins the Arlington grammar commit SHA for provenance.
logger()->info('arlington', [
'rule' => $finding->ruleId,
'severity' => $finding->severity,
'grammarSha' => $finding->grammarSha,
]);
}
  • PdfRValidator 基于正则表达式,并非完整的 parser(解析器)。 它针对 NextPDF\Writer\PdfRWriter 的确定性输出。它的作用是该 writer 的偏离检测器。它并不是一个通用的 PDF parser。
  • 零发现项 ≠ 完整的 PDF/R-1 一致性。 §6.7(增量更新)与 §6.8(加密)并未在 v5.1.0 集合中实现,且已在 claims.json 中声明为范围之外。请把无发现项的结果视为「在已实现的条款集上没有偏离」,仅此而已。
  • Arlington 是建议性的。 在当前周期中,validateReportOnly() 永远不会让构建失败。CI 会使用这份产物。它不会将其作为闸门。
  • PDF/A ICC 验证不在这里。 ISO 19005-4:2020 §6.2.2 的 OutputIntent ICC 验证位于 Enterprise 版的 PdfAManagernextpdf/pro),而不在 Core 的 Compliance 模块中。Core 的 PDF/A 接口只有 ConformanceMode 这个区分器。
  • 豁免会保留审计轨迹。 被豁免的规则会从发现项列表中抑制,但豁免项目仍是记录 为何 这样处理的依据。

PdfRValidator::validate() 是对字节流的一次线性遍历,并配合有界的正则表达式遍历。成本随文件大小扩展,并稳定落在模块预算之内。ArlingtonValidator 在仅语法模式下,生成加载证明发现项的复杂度为 O(grammar-rule-count)。参考检查器路径会启动一个子进程,其上限由上游工具决定,而不是由 NextPDF 决定。它是一个异步的(out-of-band)CI 步骤。

这些验证器会读取不受信任的 PDF 字节。PdfRValidator 会在提取键值之前先剥除括号内字面量与十六进制字面量,因此精心构造的 Creator 字符串无法注入假的 /Name 键值(ISO 32000-1:2008 §7.3.4.2 转义处理)。Arlington 适配器会以有界的子进程执行上游检查器。它会把超时或执行错误视为「无发现项」,而不会信任不完整的输出。关于 PDF 解析的攻击面,请参阅本项目的威胁模型。

标准条款Compliance 模组的作用状态
ISO 23504-1:2020(PDF/R-1 标准)§6.5.7PdfRValidator 强制执行 {q,Q,cm,Do} 内容流运算符允许列表Verified(单元测试+标准配置文件测试+集成测试皆通过)
ISO 23504-1:2020(PDF/R-1 标准)§6.4.3PdfRValidator 强制执行 Info 字典键值允许列表已验证(有测试支持)
ISO 23504-1:2020(PDF/R-1 标准)§6.7、§6.8未在 v5.1.0 集合中实现明确不涵盖的范围(在 claims.json 中声明)
ISO 32000-2:2020(PDF 2.0)§7.5.2Catalog 键值允许列表遍历Claimed(正则表达式遍历;结构性)
ISO 19005-4:2020(PDF/A-4 标准)§6.7.3通过一致性模块对识别架构(identification-schema)的认知交叉参照(见 /specifications/pdfa4/ 一节)

支持不等于一致性。 一次返回零发现项的 PdfRValidator 执行,只证明输入没有偏离 该验证器所实现的 §6 条款。它并不断言该文件是一份符合 PDF/R-1 的文件:§6.7 与 §6.8 并未受检。Arlington 交叉检查是建议性的,永远不会断言一致性。对于 PDF/A-4,权威验证器是 veraPDF,以异步方式执行;关于 veraPDF oracle 及其可选用的闸门,请见 一致性模块

引用内容均改写自 NextPDF 合规语料库。完整的 64 字符 reference_id 摘要记录于页面 front-matter 与 _normative-evidence-conf.md 中。