Show HN: Tetris in a PDF

th0mas.nl

1289 points by ThomasRinsma 2 years ago


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

weinzierl - 2 years ago

It's hard to overstate the ingenuity that went into this!

Despite what people say in the comments here, both browsers really do not let you execute PDF JavaScript willy nilly. Outside of browser environments you are mostly safe anyway because JavaScript is rarely supported, with the big exception being Acrobat. The cleverness of pdftris is not so much Tetris in PDF but how it found its way around the restrictions that browser environments have put up to protect us.

From what I understand pdftris also only works because of user interaction. I think there is no way to run JavaScript in a PDF without user interaction.

MartinMond - 2 years ago

https://www.nutrient.io/blog/how-to-program-a-calculator-pdf... See here for how we did a calculator in a PDF

freedomben - 2 years ago

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"

internetter - 2 years ago

Atari Breakout for PDF: https://cdn.jsdelivr.net/gh/osnr/horrifying-pdf-experiments@...

efitz - 2 years ago

This is amazing and terrifying (I am a security engineer and parsing complex document formats is a never-ending treasure trove of vulnerabilities).

bityard - 2 years ago

Not just web browsers, Acrobat (and probably other PDF readers) have supported executing Javascript in PDFs for decades.

LetsGetTechnicl - 2 years ago

This is an affront against god. Good work.

btown - 2 years ago

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.

_yb2s - 2 years ago

This is horrifying, PDFs should not be able to execute code.

chaps - 2 years ago

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.

seany - 2 years ago

This is great. Will probably give the fun police in r/k12sysadmin a heart attack.

bwjx - 2 years ago

This is awesome.

Took a bit of prompting but was able to get a semi-working (only in Chrome) Flappy Bird out of Claude in ~10 minutes. Seems like the collision detection needs some work :)

https://github.com/baileywjohnson/flapdfy-bird/blob/main/fla...

illegalmemory - 2 years ago

Not only web but majorly all OS pdf renderers support JS. It used to be a major source of malware long back.

toddm - 2 years ago

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!

frizlab - 2 years ago

Fortunately this does not work in Safari where the rendering is done natively.

GaggiX - 2 years ago

Kinda happy that Evince doesn't start executing JS when opening a PDF.

weinzierl - 2 years ago

"It was a bit tricky to find a union of features that work in both engines [..]"

I am curious what the constraints are to make this work and in which environments it does? Does it work in PDF viewers outside the browser? Is there documentation what is available in which environment? What is enabled by default, can be switched on or off?

alphabet9000 - 2 years ago

amazing, i didn't know PDF supported javascript.

i've tried making "interactive" PDFs before but using POST and server side rendering rather than client, e.g. a PDF typewriter i made a little while back on http://news.coffee

Uptrenda - 2 years ago

Well OP, you have definitely made me reconsider my assumptions about PDFium. I had assumed that JS didn't work altogether in Chrome. But clearly there's just bugs in the code I wrote. You've inspired me to have another crack at solving it. But definitely when the time is right. It's going to be a lot of hair pulling, I can see that now.

I'm not sure what your process was for testing your scripts: but for me because there was no meaningful error output I had to incrementally build up my script line by line (which took forever.) So I thought I'd done well when I got my stuff working in Adobe + Firefox. I wonder if now everyone is going to add similar scripts to their resumes :p Doom will be next, maybe?

kvirani - 2 years ago

Wow... It's only January. I'm so excited to see what you release in February and beyond!

random_i - 2 years ago

Playable where?

It doesn't work in the Adobe Chrome PDF viewer, or in Preview.

8mobile - 2 years ago

playing Tetris on a pdf is the last thing I would have thought of. Kudos for the idea and implementation. To start a new game do I have to reload the pdf? Thanks

krick - 2 years ago

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.

maalber - 2 years ago

This is hilarious

potatoman22 - 2 years ago

This is a good reminder for why to not download random PDFs. One of the mechanisms of the Pegasus spyware was emulating a computer inside a PDF.

https://en.wikipedia.org/wiki/Pegasus_(spyware)#Vulnerabilit...

eximius - 2 years ago

Interesting!

Something neat I found, you're able to 'clip' the blocks into each other by spinning them right before the block settles.

jeffhuys - 2 years ago

I actually am kind-of happy that this doesn't work on Mac (if you don't install Acrobat) / preview.

rhokstar - 2 years ago

I would be surprised if Doom was playable in a PDF that was being read in a LCD screen of a thermometer.

amunozo - 2 years ago

Lol, I love it. Why didn't you include points multipliers when more than one line is filled though?

ReneFroger - 2 years ago

I'm wondering if running Doom in PDF files might be achievable, or is that a step too far away?

kleiba - 2 years ago

A friend of mine once applied for a job with the local PT operator. For that, I finagled the PDF of his CV such that after a minute or so, one of the company's trains would drive over the page from left to right at the very bottom.

He never heard back from them.

theginger - 2 years ago

I hope to see this evolved into doom by the end of the year. And it better not be just monochrome

shekywakey - 2 years ago

Will you call it the "Thomas Engine" that powers simple GUI games on PDF?

Uptrenda - 2 years ago

I did the same but with snake: https://roberts.pm/resume.pdf (Game at bottom -- though only works in Firefox and adobe. Now I need to add chrome support, thanks op. lmao)

Edit: here's the code for my snake game too, btw = https://github.com/robertsdotpm/resume/blob/main/snake.js

riffraff - 2 years ago

could you use checkboxes for display? I'm no sure if you can style them, but I think you can access them in JS, and that should result in having basic "pixels" which you can use to draw anything.

freedomben - 2 years ago

A few questions if you're willing:

1. What led you to want to do this project?

2. Have you worked with PDFs before? Do you work with PDFs as part of your day job?

3. Have you implemented Tetris before or is this your first time?

4. How long did it take you?

ilvez - 2 years ago

I'm probably lucky that Sumatra is showing them as static documents.

brumar - 2 years ago

I was considering doing exactly that ahah. We should connect to share our hacks and pains. One could project would be to run wasm4 games because, yes, pdfium and pdf.js can run webassembly.

thih9 - 2 years ago

Would this work on a simple (non-android) eink reader, like a kindle?

rgmerk - 2 years ago

This is Evil Genius level work. Congratulations!

Did you do the actual coding in Acrobat or is there a less painful way to write embedded JS in a PDF?

alana314 - 2 years ago

Wow, I had no idea PDFs could be this dynamic. Doesn't work in Mac OS preview or quicklook but works great in chrome.

ninalanyon - 2 years ago

I'm very pleased that this did not work in Firefox on Linux Mint. Unfortunately it does work in Vivaldi.

enews01 - 2 years ago

Wow this was quite fun and impressive! Looks like it doesn't work on Firefox, I wonder why.

Shinchy - 2 years ago

That's truly amazing! I knew you could do a lot with PDF but that not to this extent.

amytimed - 2 years ago

This is awesome! I think you should add the explanation of how it works in the PDF itself as well

luismedel - 2 years ago

Awesome.

I don't do security stuff anymore but I feel chills when I see (great) things like this,

casey2 - 2 years ago

I believe there is a bug with the T block, I think I managed to overlap some blocks

miningape - 2 years ago

I just wish I could print this

Uptrenda - 2 years ago

OP, I still don't really understand how you got it to work in Chrome?

abdibrokhim - 2 years ago

Warning: Error during font loading: Font "HeBo" is not available.

_bydex - 2 years ago

I dont have a kindle to test, but i wonder if this works on a kindle

chimo777 - 2 years ago

That's amazing! It goes beyond my understanding of PDFs.

nejsjsjsbsb - 2 years ago

PDFs, Regexes and Typescript Compiler make great runtimes!

_joel - 2 years ago

So does that mean we can transpile PDFs to webassembly now?

- 2 years ago
[deleted]
0xKelsey - 2 years ago

That's both awesome and terrifying security-wise.

oneandonley1 - 2 years ago

doesn't work on mobile, is there a specific viewer for this

- 2 years ago
[deleted]
jiveturkey - 2 years ago

didn't work in safari's embedded reader. no text either, just a blank page. or did i not wait long enough?

purpleidea - 2 years ago

Neat! Sadly doesn't work in Evince.

izakfr - 2 years ago

This is really awesome, great job!

lihaciudaniel - 2 years ago

Doesn't work in pdf.js

billiam - 2 years ago

and this is why I can't read HN at work anymore........

I have increasing confidence that when AIs finally destroy the Internet the delivery vehicle will be the file format that was created, as the Internet itself was, as a form of digital paper.

shivekkhurana - 2 years ago

But can it run Doom ?

tamersalama - 2 years ago

Take that RAG parser

nickcageinacage - 2 years ago

So cool

pmarreck - 2 years ago

this is a horrible idea.

which is why i am commenting to check it out later.

since postscript is also a language that it literally runs to render, would it also be possible to use postscript to make interactive elements?

zombot - 2 years ago

Holy crap, JS in a PDF! I wonder what mischief might be wrought with that.

weddingbell - 2 years ago

I printed the PDF on A4 paper, but Tetris doesn't work! lol

swyx - 2 years ago

... why exactly do PDF engines have to run javascript? wtf?

darkce - 2 years ago

so good

josefritzishere - 2 years ago

Brilliant!

Thoreandan - 2 years ago

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

Fernicia - 2 years ago

Back in school pdfs would circulate that had a bunch of flash games on them. I have no idea how or who made them, but they let us play dolphin olympics on lab computers with no internet connection.

mati365 - 2 years ago

So it's possible to port C compiler to PDF. Compiler is already done https://github.com/Mati365/ts-c-compiler. We can run DOS in PDF basically..

cool-RR - 2 years ago

I printed it but it doesn't work :(

ustad - 2 years ago

That reminded to disable javascript in pdfjs that is used in firefox.

Feel much safer!

Elizabeth0147 - 2 years ago

[dead]

meddah - 2 years ago

Oops. I realized now, unknown PDFs are not safe.

tonetheman - 2 years ago

[dead]

fishstock25 - 2 years ago

[dead]