Bỏ qua để đến nội dung

Phân tích cú pháp và kiểm tra tệp PDF để lấy thông tin cấu trúc

Công thức này dùng phương án dự phòng Quick của trình kiểm tra Core để đọc thông tin cấu trúc từ tệp Portable Document Format (PDF). Bạn sẽ nhận được phiên bản, số trang, cờ mã hóa, cờ chữ ký, cờ tệp đính kèm, kích thước tệp và các cờ rủi ro. Quick chạy hoàn toàn trong tiến trình, không cần sidecar Spectrum và không truy cập mạng. Hãy dùng nó để phân loại nhanh, chứ không phải để kiểm định.

Terminal window
composer require nextpdf/core:^3

Tệp PDF ghi phiên bản của nó trong phần đầu tệp (ISO 32000-2 §7.5.2). Phần trailer chứa một mã định danh tệp (/ID) dưới dạng hai chuỗi byte (ISO 32000-2 §7.5.5). Khi có chữ ký, từ điển chữ ký lưu trữ Cryptographic Message Syntax (CMS) SignedData được mã hóa theo Distinguished Encoding Rules (DER) trong Contents (ISO 32000-2 §12.8.1). Phương án dự phòng Quick dùng một phép quét có giới hạn trên các byte của tài liệu để rút ra phiên bản, ước lượng số trang, cùng các cờ cho biết sự hiện diện của mã hóa, chữ ký và tệp đính kèm.

Tạo new Inspector(), rồi gọi ->inspect(string $pdfData, InspectConfig::quick()). Lệnh này trả về một InspectResult gồm $pdfVersion, $pageCount, $isEncrypted, $hasSigned, $hasAttachments, $fileSizeBytes, $riskFlags, và hàm trợ giúp hasRisks().

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Inspect\InspectConfig;
use NextPDF\Inspect\Inspector;
$pdf = file_get_contents(__DIR__ . '/document.pdf');
$result = (new Inspector())->inspect($pdf, InspectConfig::quick());
printf(
"v%s, %d page(s), encrypted=%s, signed=%s\n",
$result->pdfVersion ?? '?',
$result->pageCount,
$result->isEncrypted ? 'yes' : 'no',
$result->hasSigned ? 'yes' : 'no',
);

Chương trình độc lập này chạy trong bộ khung kiểm thử cookbook. Nó bám theo examples/39-parse-and-inspect-pdf.php: dựng một tệp PDF nhiều trang nhỏ trong bộ nhớ, đọc thông tin cấu trúc của tệp bằng phương án dự phòng Quick, rồi định tuyến dựa trên những thông tin đó, tuyệt đối không dựa trên phán quyết về độ tin cậy. Nhánh định tuyến chỉ mang tính minh họa. Hãy thay thế nó bằng pipeline, hàng đợi trình xác minh và khu cách ly của riêng bạn.

<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Core\Document;
use NextPDF\Inspect\InspectConfig;
use NextPDF\Inspect\Inspector;
// A self-contained input so the program runs with no external file.
$doc = Document::createStandalone();
$doc->setTitle('Parse-and-inspect demo');
$doc->setAuthor('NextPDF Cookbook');
$doc->addPage();
$doc->setFont('helvetica', '', 12);
$doc->cell(0, 10, 'Page one of the parse-and-inspect demonstration.', newLine: true);
$doc->addPage();
$doc->cell(0, 10, 'Page two.', newLine: true);
$pdf = $doc->getPdfData();
$result = (new Inspector())->inspect($pdf, InspectConfig::quick());
echo 'PDF version : ' . ($result->pdfVersion ?? 'unknown') . "\n";
echo 'Pages : ' . $result->pageCount . "\n";
echo 'Encrypted : ' . ($result->isEncrypted ? 'yes' : 'no') . "\n";
echo 'Signed : ' . ($result->hasSigned ? 'yes' : 'no') . "\n";
echo 'Attachments : ' . ($result->hasAttachments ? 'yes' : 'no') . "\n";
echo 'File size : ' . $result->fileSizeBytes . " bytes\n";
echo 'Risk flags : ' . ($result->hasRisks() ? count($result->riskFlags) : 0) . "\n";
// Route on structural facts, not trust verdicts. Replace these calls with
// your own pipeline / verifier queue / quarantine.
if ($result->isEncrypted) {
// $pipeline->decryptThenContinue($pdf);
echo "Route: decrypt-then-continue\n";
} elseif ($result->hasSigned) {
// $verifierQueue->enqueue($pdf); // see the signature-inspect recipe
echo "Route: enqueue for cryptographic verification\n";
} elseif ($result->hasRisks()) {
// $quarantine->hold($pdf, $result->riskFlags);
echo "Route: quarantine (risk flags present)\n";
} else {
// $pipeline->continue($pdf);
echo "Route: continue (no risks, unsigned, unencrypted)\n";
}
// The harness sets NEXTPDF_COOKBOOK_OUTPUT and runs this script under the
// semantic profile; emit the document to the side-channel.
$out = getenv('NEXTPDF_COOKBOOK_OUTPUT');
file_put_contents($out !== false && $out !== '' ? $out : __DIR__ . '/inspected.pdf', $pdf);

Đầu ra chuẩn (STDOUT) dự kiến (phiên bản và kích thước tùy thuộc vào bản dựng; tệp PDF demo không mã hóa, không ký và không có rủi ro):

PDF version : <version>
Pages : 2
Encrypted : no
Signed : no
Attachments : no
File size : <n> bytes
Risk flags : 0
Route: continue (no risks, unsigned, unencrypted)
  • Quick dùng để phân loại, không phải để kiểm định. Nó báo cáo những gì hiện diện và những gì vắng mặt. Nó không xác minh chữ ký, không giải mã nội dung, cũng không khẳng định mức độ tuân thủ. Hãy xem kết quả như dữ liệu đầu vào cho việc định tuyến.
  • Số trang là giá trị ước lượng. Phương án dự phòng Quick đếm các dấu hiệu của đối tượng trang. Một đồ thị đối tượng bị cố tình làm dị dạng có thể làm sai lệch số đếm. Hãy dùng các mức độ sâu được Spectrum hỗ trợ khi bạn cần số đếm chính xác.
  • Standard/Full cần sidecar. new InspectConfig() (mức độ sâu Standard) và InspectConfig::full() cần sidecar Spectrum. Chúng ném ra INSPECT-SIDECAR-001 khi sidecar không khả dụng và không âm thầm hạ cấp về Quick.
  • Đầu vào rỗng. Truyền vào một chuỗi rỗng sẽ ném ra ngoại lệ inspect với “PDF data must not be empty”.
  • Phạm vi của cờ mã hóa. Cờ này phản ánh một mục /Encrypt trong trailer. Trình kiểm tra sẽ không giải mã tệp đã được gắn cờ.

Phương án dự phòng Quick dùng một phép quét có giới hạn, không phải phân tích cú pháp đầy đủ. Hãy dùng nó để định tuyến trước cho khối lượng lớn tệp đầu vào trước khi xử lý nặng hơn.

Trình kiểm tra chạy trong tiến trình và chỉ đọc các dấu hiệu cấu trúc. Không byte nào của tài liệu rời khỏi máy chủ, và không văn bản nào của tài liệu được trích xuất. Một cờ rủi ro, chẳng hạn như JavaScript được nhúng, là tín hiệu gợi ý cho việc định tuyến. Đó không phải là lời khẳng định rằng tệp an toàn hay không an toàn.

Phát biểuĐặc tảĐiều khoảnreference_id
Phần đầu tệp ghi phiên bản PDF.ISO 32000-2§7.5.2
Mục /ID trong trailer là một mã định danh tệp gồm hai chuỗi byte.ISO 32000-2§7.5.5
Mục Contents của từ điển chữ ký lưu giữ DER CMS SignedData.ISO 32000-2§12.8.1

Công thức này chỉ báo cáo thông tin cấu trúc. Nó không khẳng định rằng tệp hợp lệ, an toàn hay tuân thủ.

Các mức độ sâu kiểm tra Standard và Full chạy qua sidecar Spectrum. Chúng bổ sung phân tích chi tiết hơn về đối tượng, phông chữ và hình ảnh. Phương án dự phòng Quick được mô tả ở đây thuộc Core và hoạt động ngoại tuyến.