في مسارات عمل الطباعة والأرشفة وامتثال المستندات في المؤسسات، لا يمكن ببساطة "عرض" ملف PDF. يجب تدقيقه. قد يحتوي ملف PDF على مجموعات شفافية غير مسطحة (unflattened transparency groups) تؤدي إلى تعطل معالجات الصور النقطية (RIPs) القديمة، أو تعليمات JavaScript مضمنة تشكل خطرًا أمنيًا، أو صورًا منخفضة الدقة ستبدو مروعة عند طباعتها بدقة 300 نقطة في البوصة (DPI).
تُعرف عملية فحص ملف PDF قبل دخوله في سير عمل الإنتاج باسم الفحص المسبق (Preflighting). في هذه المقالة، سنستكشف كيفية بناء أداة آلية للفحص المسبق وتدقيق المخاطر في Delphi من خلال الاستفادة من إمكانات التحليل منخفضة المستوى لـ PDFium.
فحوصات الفحص المسبق الرئيسية
يتحقق تدقيق المخاطر القياسي عادةً من العناصر التالية داخل ملف PDF:
- العناصر التفاعلية: إجراءات JavaScript، وإجراءات التشغيل (Launch actions - لتنفيذ برامج خارجية)، ونماذج AcroForms.
- مقاييس الموارد: وجود صور منخفضة الدقة أو خطوط مضمنة مفقودة.
- حالة الأمان: تشفير المستندات، ومتطلبات كلمة المرور، وأذونات الوصول (على سبيل المثال، تعطيل الطباعة).
- معايير المستندات: التحقق من صحة علامات توافق PDF/A أو PDF/X في البيانات الوصفية للمستند.
استخراج البيانات الوصفية لـ PDF والتعليقات التوضيحية باستخدام PDFium
يوفر PDFium واجهة برمجة تطبيقات C قوية يمكن لـ Delphi استهلاكها. لإجراء تدقيق فحص مسبق، لا نقوم فقط بعرض الصفحة؛ بل نسير عبر شجرة كائنات PDF. لنلقِ نظرة على كيفية التكرار عبر صفحات المستند وفحص التعليقات التوضيحية (annotations) للعثور على إجراءات JavaScript التي قد تكون محفوفة بالمخاطر.
uses
System.SysUtils, pdfium_lib;
procedure AuditPdfSecurity(const FileName: string);
var
Doc: FPDF_DOCUMENT;
PageCount, i, j: Integer;
Page: FPDF_PAGE;
AnnotCount: Integer;
Annot: FPDF_ANNOTATION;
AnnotSubType: FPDF_ANNOTATION_SUBTYPE;
Action: FPDF_ACTION;
ActionType: ULONG;
begin
FPDF_InitLibrary();
try
// Load the document without a password
Doc := FPDF_LoadDocument(PAnsiChar(AnsiString(FileName)), nil);
if Doc = nil then
raise Exception.Create('Failed to load document or password required.');
try
PageCount := FPDF_GetPageCount(Doc);
Writeln(Format('Auditing %d pages...', [PageCount]));
for i := 0 to PageCount - 1 do
begin
Page := FPDF_LoadPage(Doc, i);
if Page <> nil then
begin
AnnotCount := FPDFPage_GetAnnotCount(Page);
for j := 0 to AnnotCount - 1 do
begin
Annot := FPDFPage_GetAnnot(Page, j);
if Annot <> nil then
begin
AnnotSubType := FPDFAnnot_GetSubtype(Annot);
// Check for Link Annotations that might have malicious actions
if AnnotSubType = FPDF_ANNOT_LINK then
begin
Action := FPDFAnnot_GetLinkAction(Annot);
if Action <> nil then
begin
ActionType := FPDFAction_GetType(Action);
// 2 represents PDFACTION_URI, 3 represents PDFACTION_SOUND, 4 represents PDFACTION_MOVIE
// We specifically look out for PDFACTION_LAUNCH or PDFACTION_JAVA_SCRIPT
if (ActionType = PDFACTION_JAVA_SCRIPT) or (ActionType = PDFACTION_LAUNCH) then
begin
Writeln(Format('WARNING: Malicious action detected on page %d', [i + 1]));
end;
end;
end;
FPDFPage_CloseAnnot(Annot);
end;
end;
FPDF_ClosePage(Page);
end;
end;
finally
FPDF_CloseDocument(Doc);
end;
finally
FPDF_DestroyLibrary();
end;
end;
التحقق من دقة الصورة
تعتبر الخطوة الحاسمة الأخرى للفحص المسبق لمسارات عمل الطباعة هي التأكد من عدم انخفاض أي صورة عن حد معين للنقاط في البوصة (DPI). يتيح لك PDFium استخراج كائنات الصور مباشرة من تيار الصفحة. من خلال قسمة أبعاد البكسل للصورة المستخرجة على الأبعاد المادية (بالنقاط) التي تشغلها على صفحة PDF، يمكنك حساب DPI الفعال.
procedure AuditPageImages(Page: FPDF_PAGE);
var
ObjCount, i: Integer;
PageObj: FPDF_PAGEOBJECT;
ImgWidth, ImgHeight: Integer;
begin
ObjCount := FPDFPage_CountObjects(Page);
for i := 0 to ObjCount - 1 do
begin
PageObj := FPDFPage_GetObject(Page, i);
if FPDFPageObj_GetType(PageObj) = FPDF_PAGEOBJ_IMAGE then
begin
FPDFImageObj_GetBitmap(PageObj); // Returns an FPDF_BITMAP you can inspect
// Retrieve metadata using FPDFImageObj_GetImageMetadata
// Calculate effective DPI based on quad coordinates
end;
end;
end;
التكامل مع PDFium Component
يتطلب بناء محرك فحص مسبق قوي من الصفر باستخدام واجهة برمجة تطبيقات PDFium C الخام تعليمات برمجية تأسيسية كبيرة ومعرفة عميقة بمواصفات PDF. استخدام غلاف (wrapper) يبسط هذا بشكل كبير. باستخدام غلاف Delphi عالي المستوى، يمكنك تحويل تكرارات مؤشرات C المعقدة إلى كود نظيف موجه للكائنات.
من خلال أتمتة مرحلة الفحص المسبق، فإنك تمنع الملفات السيئة من إعاقة خط الإنتاج الخاص بك، مما يوفر الوقت وموارد العرض.
ملاحظة: عمليات التحليل المتقدمة لـ PDF وإمكانات الفحص المسبق مدعومة بالكامل بواسطة مكون PDFium Component VCL.