コンピューターの世界には古いジョークがある。DOOM はいずれ何の上でも動く、というものだ。ゲームへの賛辞ではなく、挑戦としての言い回しである。1993年のこのシューティングは、これまでに現金自動預払機、プリンター、妊娠検査薬、電卓、たった一個のレゴブロック、そして MacBook のタッチバーの上で動かされてきた。
2025年1月、ある高校生がこの一覧にもう一項目を書き加えた。DOOM をPDFファイルの中で動かしたのである。

手短に言うと
高校生が2020年版の Emscripten で DOOM を asm.js にコンパイルし、画面の各行に一つずつフォームフィールドを割り当てて表示装置とし、PDFの中で動かした。320×200、六階調のグレー、1フレームあたり約80ミリ秒。脆弱性は一切関係していない。使われている機能はすべてPDF仕様に文書化されたものであり、設計どおりに動いているだけだ。面白いのはまさにそこ——そして、書類に一度だけ十分ほど注意を向ける理由もそこにある。
見事な仕事であり、とても良いジョークでもある。同時に、このサイトが繰り返し述べていて、そして人々が信じにくいのももっともな一点を、最も明快に示す実例でもある。PDFはページの写真ではない。コードを実行できる容れ物なのだ。
実際のしくみ
プロジェクト名は doompdf、作者は ading2210 と名乗る開発者である。しくみのほうが芸当そのものより面白く、四つの部分から成る。
PDFはJavaScriptに対応している。アドオンでもプラグインでもなく、独自の標準ライブラリを備えた形式の一部であり、ブラウザーも内蔵PDFエンジンの中でこれを実装している。フォームが入力内容を検証し、対話的な文書がクリックに反応できるようにするためのものだ。誰もゲームのために加えたわけではない。
DOOMのソースコードは公開されている——ただし実際の経緯は、この短い言い方よりも細かい。id Software がコードを公開したのは1997年12月23日だが、そのライセンスは教育目的の利用しか認めておらず、しかも公開されたのは DOS 版ではなくLinux 移植版のコードだった。音声ライブラリ DMX のライセンスが別だったためである。GPL への変更は約二年後、1999年10月3日に行われた。重要なのはこの二つ目の日付だ。DOOMは「読めるもの」から「合法的に作り直せるもの」になった。だからこそ、このゲームは思いがけない場所に現れ続ける。
両者を橋渡ししたのは、意図して古いままのコンパイラだった。ading2210 が使ったのは Emscripten 1.39.20——2020年の版である。WebAssembly ではなく asm.js を出力するからだ。現在の Emscripten は WebAssembly を生成するが、PDFには WebAssembly の実行環境がない。asm.js は通常のJavaScriptの制限された方言なので、JavaScriptが動く場所ならどこでも動く。古い道具を持ち出したのは懐古趣味ではなく、それが唯一の入口だったからである。
残るのは表示だ。ここが声を上げて笑ってしまう部分である。PDFにはキャンバスもフレームバッファーもなく、ピクセルを塗る先が何もない。あるのはフォームフィールドだ。そこでゲームの320×200の出力はASCII文字で描かれる——画面の各行につき一つのテキストフィールド、六階調のグレーで——そしてその文字列を書き直せる速さで更新される。おおよそ1フレーム80ミリ秒という計算だ。入力も同じ道を通る。PDFエンジンがもともと扱い方を知っているフィールドとボタンである。文字どおり、記入用フォームの中でDOOMを遊んでいることになる。
動作は遅い。単色である。それでも完全に遊べる。基にしたコードと同じくGPL v2で公開されており、Chromium系のブラウザーで自分で試せる。ビルドは自分のWADファイルを差し込むことまで許している。
その後、彼はPDFの中でLinuxを起動した
数週間後、同じ開発者は linuxpdf を公開した。PDFファイルの中で完全なLinuxカーネルが起動する——RISC-Vエミュレーター TinyEMU を同じ asm.js の手口でコンパイルしたのである。カーネルの起動には30〜60秒かかり、作者はこれを実機の百倍以上遅いと表現している。操作はPDFのボタンで組み上げた仮想キーボードで行う。
文書の中のDOOMはジョークだ。文書の中でエミュレートされたCPUがオペレーティングシステムを起動するとなると、それは主張である。この二つのあいだのどこかで、話はもうDOOMのことではなくなる。
笑えない部分
ここが立ち止まって考える価値のあるところだ。doompdfには脆弱性の悪用が一切ない。欠陥が見つかったわけでも、何かが破られたわけでも、セキュリティホールが関係したわけでもない。使われているものはすべて、PDF仕様に文書化された意図的な機能であり、設計どおりに動いている。

つまり、PDFに1993年のシューティングを動かさせるその能力は、あなたが明日開く請求書の中にも同じように存在している。潜んでいるのでも隠れているのでもなく、ただそこにあって使われていない。大半の文書にはそれを使う理由がないからだ。
これがこの話の正直な形であり、そして両側を切る。「文書はコードを実行できるのだから用心を」という理屈は、そのコードが置かれた世界がいかに狭いかも認めなければならない。
PDF内のスクリプトにできること・できないこと
doompdfをめぐる記事の多くはここで曖昧になるので、具体的に書いておきたい。答えはそのファイルを何で開いたかにすべてかかっており、よくある二つの場合は大きく異なる。
| できること | ブラウザーの表示機能(Chrome、Edge、Firefox) | Adobe Acrobat Reader |
|---|---|---|
| 開いた瞬間にスクリプトを実行する | できる | できる(無効化していなければ) |
| フォームフィールドの読み書き | できる | できる |
| Cookieやブラウザーの保存領域を読む | できない | 該当しない |
| 周囲のHTMLページ(DOM)に触れる | できない | 該当しない |
| ネットワーク要求を出す | ごく限定的 | より広い——追跡用ピクセルやNTLM漏洩はここに棲んでいた |
| ローカルファイルに触れる | できない | 制限つき。ただしAPIの面積ははるかに大きい |
| 外部プログラムや添付を起動する | できない | 確認のうえで——歴史的に悪意ある文書が通ってきた道 |
この表は正しい向きで読んでほしい。ブラウザーでは、スクリプト入りのPDFは小さく退屈な箱の中で動いている。Cookieもなく、保存領域もなく、周囲のページにも触れない。doompdfが事件ではなく珍事である理由はまさにそこであり、「DOOMがPDFで動く」がPDFを恐れる理由にならない理由でもある。
興味深いのはデスクトップ用リーダーの列だ。仕様が記述するJavaScript APIを丸ごと備えている。本物の業務文書を扱うためのものだからである。文書に対して、開いた瞬間に外へ知らせるよう指示したり、リーダーごとに違う振る舞いをさせたり、持ち運んできた何かを開くよう促したりできるのは、この環境である。
したがって、ソフトが何であれ変わらない三点があり、それこそ身につけておく値打ちがある。
- PDFは、あなたが何も読まないうちに、開いた瞬間に実行される指示を運びうる。
- PDFは、開くソフトによって振る舞いが変わりうる。あなたが見ているファイルは、同僚が見ているものと同じとはかぎらない。
- PDFは見せている以上のものを運ぶ。添付、隠しレイヤー、改訂履歴、そして送るつもりのなかったメタデータ。
これらのどれも、日常的な意味でPDFを危険にするものではない。今月あなたは何十件も開くだろうし、そのすべてが問題なく済む。ただ、私たちの多くが抱えている「ただの文書だ」という思い込みが、ときに意味を持つ形で誤っている、ということではある。
ほとんど誰も知らない設定
定番の助言は「PDFリーダーでJavaScriptを切りなさい」であり、良い助言だ。しかしそれだけでは不完全である。多くの人はもうPDFリーダーでPDFを開いていない。ブラウザーのタブで開いており、ブラウザーには別個のスイッチがある。
Firefox はPDFのスクリプトを有効のまま出荷している。設定名は about:config の pdfjs.enableScripting。Firefox 87 までは false、Firefox 88 からは true である。全体の javascript.enabled はこれに触れない。PDFビューアーは別世界であり、別の設定を持つ。
ChromeとEdge にはPDFスクリプト専用のスイッチがそもそもない。PDF内のスクリプトは、そのファイルの取得元サイトのJavaScript権限に従う。アドレスバーの制御からサイトごとに切ることも、chrome://settings/content/javascript で全体的に切ることもできるが、後者はかなり大雑把な道具である。
Adobe Acrobat Reader にこそ、誰もが思い浮かべるスイッチがある。環境設定 → JavaScript → Acrobat JavaScriptを使用。外す価値があるのはこのチェックだ。AcrobatはAPIの大きいリーダーであり、通常の業務でスクリプト入り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出力、1フレーム約80ミリ秒、GPL v2
- ading2210「linuxpdf(GitHub)」——PDF内のTinyEMU RISC-VエミュレーターでのLinux、起動30〜60秒
- 遊べる版(Chromium系ブラウザー)
- Eric Lawrence「Browser Security Bugs that Aren’t: JavaScript in PDF」——ブラウザーのPDFエンジンがスクリプトに何を許し、何を許さないか
- Adobe「Restrict JavaScript API access in Acrobat」
- DoomWiki「Licences」——1997年12月23日のコード公開、1999年10月3日のGPL移行
- The Register「It’s Doom … running in a PDF file」
- Ars Technica「This PDF contains a playable copy of Doom」


