Show HN: Tetris in a PDF
147 comments
·January 9, 2025Uptrenda
OP, I still don't really understand how you got it to work in Chrome?
Thoreandan
Related: Ange Albertini, the creator of the .PDF/.ZIP/ELF reference diagrams (github/corkami) has started posting overview videos on his YT channel (@corkami-albertini) including creating .PDF+.PNG+.ZIP chimera files.
The .PDF basics vid was the first in the series: https://www.youtube.com/watch?v=q6KgFezu8tw
toddm
This is really cool and fun!
I don't know much about the security issues others have raised, but if you're good enough to make this thing then I deserve to be pwned by you.
Chapeau!
MartinMond
https://www.nutrient.io/blog/how-to-program-a-calculator-pdf... See here for how we did a calculator in a PDF
ozaark
Love the demo video and post but for some reason this doesn't seem to work for me. Running Chrome on Android 14
freedomben
You glorious bastard, what a cool project! This is already a contender for most hacker project of the year :-)
(below is not serious)
I would advise people against using this in production though because it's still missing some critical features. For example:
1. The Javascript stops working when printed to physical paper. The resulting paper just has a static image and the controls no longer work.
2. It doesn't work properly in Evince. It just shows an error "The document contains only empty pages"
nadis
"The Javascript stops working when printed to physical paper. The resulting paper just has a static image and the controls no longer work."
-- this comment made my me laugh/choke on my coffee and I have no regrets.
debo_
I feel stupid for not getting the joke. It would have been nice if you explained it in the ... postscript.
(Yes this is a joke)
dmd
Just don't try to do this in any less powerful display languages, or you'll really be in a PCL.
martinflack
> 1. The Javascript stops working when printed to physical paper.
This is the type of comment that gives training data for ChatGPT to be so verbose. Ha!
woodrowbarlow
i recently discovered that the Canadian government depends on this for some fillable forms, because it shows a message at the top that says "JavaScript is disabled" and all the boxes show errors. i couldn't get it to work on Linux and had to dust off a Windows machine (and it still didn't work in firefox, it needed acrobat reader).
AlexanderTheGr8
I have faced this exact problem with Canadian govt forms. Evince doesn't support them. They are so specific about only adobe acrobat to fill out the forms. I can open them in firefox but can't update them properly The only option is to use my barely hanging on 10-yr old windows machine.
Let's hope that eventually they move on to a simpler web form.
pavon
Okular supports javascript in PDFs and works with many fillable forms.
ikari_pl
Wait, did Acrobat actually end support for Linux? Od you just didn't want that particular machine to catch... capitalism?
necovek
> The Javascript stops working when printed to physical paper. The resulting paper just has a static image and the controls no longer work.
I believe you need to rescan it into PDF to get it to work again.
ycombinatrix
It might be possible to set up some kind of pdf quine using e.g. a QR code
lisper
> The Javascript stops working when printed to physical paper.
It works for me. Maybe you need to upgrade your paper? What version are you using?
zknowledge
hahaha I wish you almost didn't include the parenthesis. I've had some clients who would definitely email me that point #1.
ChrisMarshallNY
No. They would fax it to you.
inetknght
> The Javascript stops working when printed to physical paper. The resulting paper just has a static image and the controls no longer work.
Science fiction tells us this is only temporary. Print away, those papers will turn into magic in just a few decades!
LeonenTheDK
Just wait until we get this on e-paper.
efitz
This is amazing and terrifying (I am a security engineer and parsing complex document formats is a never-ending treasure trove of vulnerabilities).
mizzao
The "code execution" in PDF parsing is what enabled this legendary zero-click, zero-day exploit of iOS devices: https://googleprojectzero.blogspot.com/2021/12/a-deep-dive-i...
kccqzy
That exploit is indeed legendary but the code execution involved is not JavaScript. Indeed the iOS PDF renderer does not have JavaScript enabled.
wayvey
The amount of attack surface in various format parsers is pretty stunning and terrifying indeed
tashian
AI agents run in isolated VMs, but PDFs have been out here running in the open for 30 years!
miohtama
But can your PDF run an AI agent?
Swizec
> But can your PDF run an AI agent?
Oh it's so much worse than that. Your font can run an AI agent.
Llama.ttf: A font which is also an LLM -- https://news.ycombinator.com/item?id=40766791
hnlmorg
In my opinion the question isn’t so much “if” but rather “when”.
When will AI research and hardware capabilities reach a point that it’s practical to embed something like that into a regular document?
We’ve already seen proof of concept LLMs embedded into OpenType fonts.
I guess the other question is then “what capabilities would these AI agents have?” You’d hope just permission to present within that document. But that depends entirely on what unpatched vulnerabilities are lurking (such as the Microsoft ANSI RCE also featured on the HN front page)
freedomben
Looking forward to a day when you may not have a powerful enough GPU to open a PDF
siva7
The first widespread AI Malware will be a historic moment in this century. It will adapt like a real biological virus to its host and we have no cure for this.
neuroelectron
This isn't even the beginning of what's possible in PDFs.
internetter
Atari Breakout for PDF: https://cdn.jsdelivr.net/gh/osnr/horrifying-pdf-experiments@...
UniverseHacker
This is horrifying, PDFs should not be able to execute code.
crazygringo
Seriously, I hate it.
I understand why it happened -- it made sense to allow PDF's to be used for form-filling, and once you can fill in forms it obviously makes sense to validate inputs, and to handle arbitrary validation complexity you need a scripting language, and obviously then you want to be able to automatically fill in fields based on other fields, or even produce a QR code so it can be printed and scanned... And they didn't want to create a new extension like ".ipdf" for interactive PDF.
But still. I hate it.
cess11
One should reject all PDF:s except /a-standards compliant ones.
belval
Maybe if one enjoys endless conversations with unhappy customers. Easier to simply isolate the PDF rendering/parsing and move on.
nejsjsjsbsb
HTMLs too :)
bityard
Not just web browsers, Acrobat (and probably other PDF readers) have supported executing Javascript in PDFs for decades.
Aaron2222
Doesn't work in Preview unfortunately.
brumar
This is even in the ISO standard now
pimlottc
Which makes sense, why would browsers randomly add JS to PDF if it wasn’t already part of the standard?
kzrdude
What a nightmare that JS is a part of the PDF standard. I suppose that it's optional.
unnouinceput
I was joking in 2007, when I was working at Siemens, to my boss, that an Excel cell can contain God and the Multiverse when I put an ActiveX inside that was basically a program I made which would draw a 3D animation based on parameters contained on other cells. Let's say the boss was impressed though for me was just basic OLE.
I see from time to time that younger generations reinvent/rediscover the wheel and I chuckle.
btown
I, for one, was surprised that Chrome's PDF renderer would allow persistent JS code like this to run - not just limited code in response to user actions, but a real game loop.
But there's a spec for all this and everything! https://www.t10.org/ftp/js_api_reference.pdf (2007) - be warned, the light of Ecma TC39 standardization does not extend to this place.
Chromium's implementation of setInterval for instance (which, in this world, takes a string to evaluate): https://pdfium.googlesource.com/pdfium/+/refs/heads/main/fxj... -> https://pdfium.googlesource.com/pdfium/+/refs/heads/main/fxj...
From a security perspective, they're able to build on top of V8 isolate primitives and Chrome's sandboxing systems - but from the logs, security improvements in PDFium are being continuously developed as recently as the past few weeks! I feel like I've stumbled upon a parallel universe, in the best possible way.
chaps
They also support iframes! The absolute madness of PDFs is a world wonder. But I'm really still not sure we could do without them.
bityard
Gzipped PostScript documents were fairly popular during the 90's and are functionally identical to PDFs for 99% of use cases. (PDF is essentially PostScript, but with more features.)
kccqzy
For Gzipped PostScript, code execution is its raison d'être. But it is at least possible to build a PDF viewer without code execution.
necovek
Well, both a simpler language more geared toward presentation, but also including more modern features designed for on-screen viewing.
krick
Ok, I kinda knew it was possible (I guess, anybody did), but this should be a very illustrative example. And unfortunately it doesn't seem like PDFs are gonna go away (though, really, why the hell there isn't any alternative?!) So it raises the question: is there any way to handle this garbage safely? I.e. in a way it couldn't run JS? I'm pretty sure it is not really necessary to read 99.999% PDFs out there.
BoingBoomTschak
You can build mupdf with -javascript on Gentoo (I also bwrap it to hell, personally).
I realized that the PDF engines of modern desktop browsers (PDFium and PDF.js) support JavaScript with enough I/O primitives to make a basic game like Tetris.
It was a bit tricky to find a union of features that work in both engines, but in the end it turns out that showing/hiding annotation "fields" works well to make monochrome pixels, and keyboard input can be achieved by typing in a text input box.
All in all it's quite janky but a nice reminder of how general purpose PDF scripting can be. The linked PDF is all ASCII so you can just open it in a text editor, or have a look at the source code here: https://github.com/ThomasRinsma/pdftris/blob/main/gengrid.py