r/programming • • 12h ago

Same JavaScript file plays Tetris in the browser and Snake after formatting

https://trustsig.eu/blog/javascript-divergence/

A formatter, minifier or deobfuscator can be made to turn one script into another.

You can go try out all 186 techniques with this script: https://divergence.trustsig.eu/

Or try the Tetris-Snak demo here: https://divergence-game.trustsig.eu/

0 Upvotes

9 comments sorted by

19

u/k3v_d3v 7h ago

slllllllllllllllllllllllllllllllllllllllllllllllllllllloppppppppppppppppppppppppppppppppppppp

19

u/MoTTs_ 7h ago edited 2h ago

I used prettier and checked a couple of the claimed behavior-changing transformations, and I couldn't repro any of the claims from the article. I briefly debugged into the demo page, and it looks like they "detect" formatted or not by keeping a reference copy of the minified source, and checking if the textarea source matches.

EDIT:

After more inspection, I'd like to retract (part) of my comment.

The good:

The changes in behavior are real. For two specific examples, DevTools does change + +x to ++x, and prettier will format inside a character string if it's a tag function named "css". The textarea source check I mentioned before came up because the debugger stepped into the index page.

The bad:

The article and code are written by AI, and I think they both lack clarity. The code could have been human-readable while still triggering formatter behavior changes, but instead it was all minified. And the test functions could have been named, for example, as testUnaryToIncrement or testCssTagFunction, but instead they're named as t0, t1, t2, ..., t185.

The DB variable contains long character strings of 0's and 1's that on first glance made me suspect code that was obfuscated as binary text, but this DB variable is the test expected values. It's formatted as a tab-separated character string of 0's and 1's that represent booleans, and if the 23rd character in that string is a "1", for example, then it's expected to trigger on the function t23. I think that's an obscure relationship, and it's difficult to check which tests correspond to which formatters even when you do know the relationship.

13

u/hungarian_notation 6h ago

Oh god, I'm pissed I spent any time reading this garbage.

1

u/ShinzouNingen 4h ago edited 4h ago

I got mixed results. It worked for me when copying from Firefox's formatter, but I also tried terser and couldn't reproduce the results, even the small example.

I don't think they check by the textarea source, then inserting a comment, changing the "use strict" string to something else, or making a whitespace edit would break immediately break it, and it doesn't.

Edit: it works for me in prettier 3.9.10 too. And it cannot be using the textarea, because I ran it locally in node. Downloaded the script from the page above as foo.js, and tested it like this:

⋊> ~/ ◦ node test.js                                                                                                                                                   09:22:19
This script is clean.
⋊> ~/ ◦ npx prettier test.js | node                                                                                                                                    09:22:42
You formatted this with Prettier

1

u/trustsigRobert 4h ago

Probably a config difference, I did my testing using the repl playground. And setting "module" to false.

Have a go with any other formatter/processor too! As terser is a minfier so it is a bit trickier

1

u/ShinzouNingen 4h ago

I tried with prettier first, but I actually got a JS error on the snake page. If you're curious, the error was

Uncaught SyntaxError: Failed to execute 'append' on 'Element': Invalid or unexpected token

However the example that just output the text (I edited my comment) did work with prettier.

The undeserved downvotes are crazy though. You just got unlucky with the reddit mob mentality coin flip.

1

u/trustsigRobert 4h ago

I'll look into the game demo crash from prettier, thanks.

And for the downvotes, it is reddit after all, nothing out of the ordinary :D I appreciate you helping out though.

1

u/Rustywolf 5h ago

its not even the interesting way to do this; JS literally has behaviour that changes when a newline is added.

-2

u/trustsigRobert 5h ago edited 4h ago

Everything you said is false.

This script contains every one of the 186 techniques, run it through prettier and the logic does change: https://divergence.trustsig.eu/

(You can paste the script into node or browser console anywhere. It has literally nothing to do with the text area nor does it keep a reference copy. )

It does not detect the change by any code source checking, it's not even obfuscated so I'm confused how you got it this wrong.

What you tested is a "couple" of the 186 techniques and in the wrong tools. A technique for chrome dev tools isn't going to work for prettier, obviously.

So please, don't just lie confidently, have an actual look at the post or the code.