تدور في عالم الحوسبة نكتة قديمة: DOOM سيعمل في النهاية على كل شيء. لا مديحًا للعبة، بل تحدّيًا. فقد أُجبرت لعبة التصويب الصادرة عام 1993 على العمل على أجهزة الصراف الآلي والطابعات واختبارات الحمل والآلات الحاسبة وقطعة LEGO واحدة وشريط اللمس في حاسوب MacBook.
وفي يناير 2025 أضاف طالب في المرحلة الثانوية بندًا جديدًا إلى القائمة. لقد شغّل DOOM داخل ملف PDF.

باختصار
طالبٌ ثانوي ترجم DOOM إلى asm.js بإصدار من Emscripten يعود إلى 2020، وشغّله داخل ملف PDF مستخدمًا حقل نموذج واحدًا لكل سطر من سطور الشاشة: 320×200، ستة تدرجات رمادية، ونحو 80 ملّي ثانية لكل إطار. لم تُستغل أي ثغرة أمنية. كل خاصية استُخدمت هي جزء موثّق من مواصفة PDF، تعمل تمامًا كما صُمِّمت. وهذا بالضبط هو المثير للاهتمام — وهو سبب منح مستنداتك عشر دقائق من الانتباه، مرة واحدة.
إنه عمل بديع ونكتة ممتازة. وهو أيضًا أوضح برهان على أمر يكرره هذا الموقع باستمرار، ومن حق الناس أن يصعب عليهم تصديقه: ملف PDF ليس صورة لصفحة. إنه وعاء قادر على تنفيذ التعليمات البرمجية.
كيف يعمل هذا فعليًا
اسم المشروع doompdf، وصاحبه مطوّر يعرّف عن نفسه باسم ading2210. الآلية أطرف من الاستعراض نفسه، وتتكوّن من أربعة أجزاء.
صيغة PDF تدعم JavaScript. ليس كإضافة ولا كملحق خارجي — بل كجزء من الصيغة، بمكتبة قياسية خاصة به، وتنفّذه المتصفحات في محرّكات PDF المدمجة لديها. وُجد ليتيح للنماذج التحقق مما تكتبه وللمستندات التفاعلية أن تستجيب للنقر. لم يضفه أحد وفي باله ألعاب الفيديو.
الشفرة المصدرية للعبة DOOM متاحة للعموم — وإن كانت القصة أدق مما يوحي به الاختصار. نشرت id Software الشفرة في 23 ديسمبر 1997، لكن برخصة تسمح بالاستخدام التعليمي فقط، وكانت شفرة النسخة المنقولة إلى لينكس لا الأصل العامل على DOS، بسبب الرخصة المنفصلة لمكتبة الصوت DMX. أما الانتقال إلى رخصة GPL فجاء بعد ذلك بعامين تقريبًا، في 3 أكتوبر 1999. والتاريخ الثاني هو المهم: فقد حوّل DOOM من شيء يمكن قراءته إلى شيء يمكن إعادة بنائه قانونيًا. ولهذا تظل اللعبة تظهر في أماكن غير متوقعة.
وقد جمع بين العالمين مترجمٌ قديم عن عمد. استخدم ading2210 إصدار Emscripten 1.39.20 — وهو إصدار من 2020 — لأنه ينتج asm.js لا WebAssembly. فالإصدارات الحديثة تنتج WebAssembly، وملف PDF لا يملك بيئة تشغيل لـ WebAssembly. أما asm.js فهو لهجة مقيّدة من JavaScript العادي، ولذلك يعمل حيثما يعمل JavaScript. لم يكن اللجوء إلى الأدوات القديمة حنينًا، بل كان المدخل الوحيد.
يبقى العرض على الشاشة، وهو الجزء الذي يجعل الناس يضحكون بصوت عالٍ. لا يملك ملف PDF لوحة رسم ولا ذاكرة إطار ولا أي شيء تُرسم عليه البكسلات. لكنه يملك حقول النماذج. لذلك تُرسم مخرجات اللعبة بدقة 320×200 بأحرف ASCII — حقل نصي واحد لكل سطر من سطور الشاشة، بستة تدرجات رمادية — ويُحدَّث العرض بالسرعة التي يمكن بها إعادة كتابة ذلك النص، أي نحو 80 ملّي ثانية لكل إطار. ويأتي الإدخال من الطريق نفسه: حقول وأزرار يعرف محرّك PDF كيف يتعامل معها أصلًا. أنت تلعب DOOM، حرفيًا، داخل نموذج قابل للتعبئة.
يعمل ببطء. بلا ألوان. وهو قابل للعب تمامًا، ويُوزَّع تحت رخصة GPL v2 كالشفرة التي بُني عليها، ويمكنك تجربته بنفسك في متصفح قائم على Chromium. بل تتيح النسخة المبنية إدخال ملف WAD خاص بك.
ثم شغّل لينكس داخل ملف PDF
بعد أسابيع قليلة نشر المطوّر نفسه مشروع linuxpdf: نواة لينكس كاملة تُقلع داخل ملف PDF، عبر ترجمة محاكي RISC-V المسمّى TinyEMU بالحيلة نفسها. تستغرق النواة من 30 إلى 60 ثانية للإقلاع — ويقدّر المؤلف ذلك بأكثر من مئة ضعف بطء العتاد الحقيقي — ويجري التحكم فيها بلوحة مفاتيح افتراضية مبنية من أزرار PDF.
DOOM داخل مستند نكتة. أما معالج محاكى يُقلع نظام تشغيل داخل مستند فهو حجّة. وفي مكان ما بين الاثنين، يتوقف الأمر عن أن يكون عن DOOM.
الجزء غير المضحك
هنا الفكرة التي تستحق التوقف عندها. لا شيء في doompdf يمثّل استغلالًا لثغرة. لم تُكتشف أي ثغرة، ولم يُكسر شيء، ولم تُستخدم أي فجوة أمنية. كل عنصر يستعمله خاصية موثّقة ومقصودة في مواصفة PDF، تعمل تمامًا كما صُمِّمت.

وهذا يعني أن القدرة التي تتيح لملف PDF تشغيل لعبة تصويب من 1993 موجودة أيضًا في الفاتورة التي ستفتحها غدًا. لا تتربّص ولا تختبئ — هي ببساطة هناك، دون استعمال، لأن معظم المستندات لا سبب لديها لاستعمالها.
هذه هي الرواية الصادقة، وهي تقطع في الاتجاهين. فالمنطق نفسه الذي يقول «المستند قادر على تنفيذ شفرة، فاحذر» عليه أن يعترف أيضًا بمدى ضيق العالم الذي تتحرك فيه تلك الشفرة.
ما يستطيعه سكربت داخل PDF وما لا يستطيعه
هنا تصبح معظم التغطيات عن doompdf غامضة، فلنكن محدَّدين. الجواب يتوقف كليًا على البرنامج الذي فتحت به الملف — والحالتان الشائعتان مختلفتان جدًا.
| القدرة | عارض المتصفح (Chrome وEdge وFirefox) | Adobe Acrobat Reader |
|---|---|---|
| تنفيذ سكربت عند الفتح | نعم | نعم، ما لم يُعطَّل |
| قراءة حقول النماذج والكتابة فيها | نعم | نعم |
| قراءة ملفات تعريف الارتباط أو تخزين المتصفح | لا | غير منطبق |
| الوصول إلى صفحة HTML المحيطة (الـ DOM) | لا | غير منطبق |
| إجراء طلبات شبكية | محدودة جدًا | أوسع — هنا عاشت بكسلات التتبع وتسريبات NTLM |
| الوصول إلى الملفات المحلية | لا | مقيّد، لكن مساحة الواجهة البرمجية أكبر بكثير |
| تشغيل برامج خارجية أو مرفقات | لا | بعد التأكيد — وهو تاريخيًا طريق المستندات الخبيثة |
اقرأ هذا الجدول في اتجاهه الصحيح. داخل المتصفح، يعمل ملف PDF المزوَّد بسكربتات في صندوق صغير ممل: بلا ملفات ارتباط، بلا تخزين، وبلا وصول إلى الصفحة المحيطة. ولهذا السبب بالذات يبقى doompdf طرفة لا حادثة أمنية، ولهذا فإن «DOOM يعمل داخل PDF» ليس سببًا للخوف من ملفات PDF.
العمود المثير للاهتمام هو عمود القارئ المكتبي. فهو يملك واجهة JavaScript الكاملة التي تصفها المواصفة، لأنه معدّ للتعامل مع مستندات الأعمال الحقيقية. تلك هي البيئة التي يمكن فيها أن يُطلب من مستند أن يبلّغ عن نفسه لحظة فتحه، أو أن يتصرف تصرفًا مختلفًا بحسب القارئ، أو أن يقترح فتح شيء كان يحمله معه.
إذًا تبقى ثلاثة أمور صحيحة مهما كان البرنامج، وهي التي يجدر استيعابها.
- قد يحمل ملف PDF تعليمات تُنفَّذ لحظة فتحه، قبل أن تقرأ أي شيء.
- قد يتصرف ملف PDF تصرفًا مختلفًا بحسب البرنامج الذي يفتحه: الملف الذي تراه ليس بالضرورة الملف الذي يراه زميلك.
- يحمل ملف PDF أكثر مما يعرض: مرفقات وطبقات مخفية وسجل مراجعات وبيانات وصفية لم تقصد إرسالها قط.
لا شيء من هذا يجعل ملفات PDF خطرة بالمعنى اليومي. ستفتح العشرات منها هذا الشهر وسيكون كل شيء على ما يرام. لكنه يعني أن التصور الذي يحمله معظمنا — «إنه مجرد مستند» — خاطئ على نحو يهم أحيانًا.
الإعداد الذي لا يكاد يعرفه أحد
النصيحة المعتادة هي «عطِّل JavaScript في قارئ PDF»، وهي نصيحة جيدة. غير أنها وحدها ناقصة — لأن معظم الناس لم يعودوا يفتحون ملفات PDF في قارئ PDF. يفتحونها في لسان تبويب داخل المتصفح، وللمتصفح مفتاحه المنفصل.
Firefox يأتي وسكربتات PDF مفعَّلة. الإعداد اسمه pdfjs.enableScripting في about:config؛ كان false حتى Firefox 87 وصار true منذ Firefox 88. أما المفتاح العام javascript.enabled فلا يمسّه: عارض PDF عالم منفصل بإعداد منفصل.
Chrome وEdge لا يوفران أصلًا مفتاحًا مخصصًا لسكربتات PDF. فالسكربت داخل PDF يخضع لإذن JavaScript الخاص بالموقع الذي جاء منه الملف، ويمكن تعطيله لموقع بعينه من عناصر التحكم بجوار شريط العنوان، أو تعطيلًا شاملًا من chrome://settings/content/javascript — وهي أداة أكثر خشونة بكثير.
Adobe Acrobat Reader يملك المفتاح الذي يقصده الجميع: التفضيلات ← JavaScript ← تمكين JavaScript الخاص بـ Acrobat. هذا هو المربع الذي يجدر إلغاء تحديده، لأن Acrobat هو القارئ صاحب الواجهة البرمجية الواسعة، ولا يكاد أحد يستخدم عن قصد ملف PDF مزوَّدًا بسكربتات في العمل الاعتيادي.
عمليًا: تعطيله في Acrobat وترك المتصفح وشأنه اختيار معقول ومتناسب. أما الاعتقاد بأنك عطّلته في كل مكان بينما عطّلته في Acrobat وحده، فلا.
ماذا تفعل بهذه المعلومة
الاستجابة العملية صغيرة وتستحق تلك العشر دقائق.
عطِّل JavaScript في القارئ المكتبي. في Acrobat Reader: التفضيلات ← JavaScript. يزيل ذلك فئة كاملة من المخاطر ولا يكلّفك شيئًا سوى — والاعتراف واجب — إمكانية لعب DOOM داخل حقل نموذج.
أبقِ القارئ محدَّثًا. السكربتات مدخل واحد. والعيوب في الشفرة التي تفك ترميز الخطوط والصور مدخل آخر، وهي ما تصلحه التحديثات — وهي تاريخيًا الطريق الأكثر شيوعًا.
تعامل مع المستندات غير المتوقعة بوصفها غير متوقعة. فاتورة من شركة لم تشترِ منها شيئًا قط تستحق لحظة تفكير، بأي صيغة وصلت. وهذا أثمن من أي إعداد.
لاحظ ما يجمع النقاط الثلاث: لا تطلب أي منها التوقف عن استخدام PDF ولا الارتياب في المستندات عمومًا. إنها بمثابة قفل باب البيت — رخيصة ومملة ومعقولة تحديدًا لأن الخطر صغير لكنه ليس صفرًا.
لماذا يستحق هذا المشروع الاهتمام الذي ناله
كان من السهل تصنيف doompdf في خانة «طرائف الإنترنت» والمضي قدمًا. وأزعم أنه أنفع من ذلك، لسبب لا علاقة له بمسرح الأمن.
فهم معظم الناس لصيغ الملفات مبني كليًا على ما تُستخدم فيه تلك الصيغ. المستندات للقراءة. الجداول للأرقام. الصور للنظر. وهذا النموذج يصحّ في معظم الأحوال، ولذلك يصعب زحزحته — ولذلك يُقابَل شرح «ملف PDF قد يحتوي محتوى نشطًا» بتشكيك مهذّب في العادة.
لعبة قابلة للعب داخل مستند تنجز في عشر ثوانٍ ما يشقّ على مقال إنجازه في ألف كلمة. تستبدل بادعاء مجرّد شيئًا يمكنك النقر عليه.
والنقطة الأعمق تتجاوز PDF بكثير. فالصيغ تراكم الخصائص عبر عقود. وكل إضافة كانت منطقية لشخص يحل مشكلة حقيقية — التحقق من النماذج مفيد فعلًا، ومستندٌ يراجع حساباته بنفسه مفيد كذلك. والنتيجة أن الأشياء العادية التي نتبادلها يوميًا أقدر بكثير مما توحي به أسماؤها. والقدرة، متى دخلت مواصفةً ما، صارت متاحة لكل من يقرأ تلك المواصفة.
ما يبقى من هذا في الاستخدام اليومي
لا شيء هنا حجة ضد صيغة PDF. فهي تظل أفضل صيغة لإرسال مستند يبدو متطابقًا في كل مكان، على أي جهاز، وبعد سنوات. وهذه مشكلة صعبة حقًا، وقد حلّتها PDF. والخصائص التي جعلت doompdf ممكنًا هي نفسها التي تجعل نموذجًا ضريبيًا قابلًا للتعبئة ممكنًا.
إنها حجة لصالح معرفة ما تتعامل معه. فالمرونة نفسها التي تتيح لمستند أن يحمل لعبة تتيح له أن يحمل سكربتات ومرفقات وطبقات مخفية وبيانات وصفية لم تقصد إرسالها. يستحق ذلك الفهم، ولا شيء منه يدعو إلى الذعر.
وهو أيضًا جزء من سبب عمل PDF Manipulator بالكامل على حاسوبك أنت. فعند دمج الملفات أو تقسيمها أو تحويلها، كلما قلّ عدد الأطراف كان أفضل — لا لأن الخدمات عبر الإنترنت شريرة، بل لأن مستندًا لم يغادر جهازك قط أسهل كثيرًا في التفكير فيه من مستند مرّ على خادوم شخص آخر.
اعمل على ملفات PDF دون اتصال تمامًا — PDF Manipulator مجاني →


المصادر
- ading2210، doompdf على GitHub — الشفرة المصدرية والوصف التقني؛ Emscripten 1.39.20، مخرجات 320×200 بستة تدرجات، نحو 80 ملّي ثانية لكل إطار، رخصة GPL v2
- ading2210، linuxpdf على GitHub — لينكس على محاكي RISC-V المسمّى TinyEMU داخل ملف PDF، إقلاع خلال 30–60 ثانية
- النسخة القابلة للعب (المتصفحات القائمة على Chromium)
- Eric Lawrence، Browser Security Bugs that Aren’t: JavaScript in PDF — ما تسمح به محرّكات PDF في المتصفحات للسكربتات وما لا تسمح به
- Adobe، Restrict JavaScript API access in Acrobat
- DoomWiki، Licences — نشر الشفرة في 23 ديسمبر 1997، والانتقال إلى GPL في 3 أكتوبر 1999
- The Register، It’s Doom … running in a PDF file
- Ars Technica، This PDF contains a playable copy of Doom
