Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
You Don't Know GIF – An analysis of a GIF file and some weird GIF features (darrien.dev)
226 points by fagnerbrack on March 10, 2022 | hide | past | favorite | 41 comments


>Now the first line ends like this which is still a perfectly valid gif. How might that look?

>Amazing! Stupendous! Wonderful! As of the time of this writing, it’s just a perfectly black square. And this is the case in every single renderer I’ve tried. Gimp, Chrome, Firefox, Preview, gifiddle, you name it.

Funnily enough in my browser (Firefox on Ubuntu) it's transparent, but it's level of transparency I have never seen before - I can see the window below.



Wow, with the line of code found in under an hour.

Mozregression looks amazing: https://mozilla.github.io/mozregression/


It's now 8 days later, and it's fixed in the nightly build. Although in contrast to what it says in the blog post, it's a perfectly white square.


This feels like the equivalent of patching the ai in GTA cars, so they can no longer randomly crash into each other and cause huge pileups. If no one can turn it into a working exploit, it should be left alone for the sheer weird/cool factor.


I agree, but it does feel like it has a lot of exploit potential.


If Firefox is maximized I just see other text on the page as I scroll. If I make it a floating window I sometimes see other page content and sometimes see the window below. Very strange.

I wonder if this could be used for some sort of phishing attack by tricking the user into thinking it is some OS trusted dialog or just showing that you know something secret so you should be trusted (would be hard to set up to work with any sort of probability though).


I took a screenshot[0] using the firefox utility and the result is a black rectangle.

It's even funnier when I open the dev tools, the transparent image is replaced by a violet rectangle, blinks a few times then stay violet[1]!

[0]: https://up.l3m.in/file/1646929301.png [1]: https://up.l3m.in/file/1646929762-a.webm


Same for me, I can see my wallpaper and desktop icons. Very strange. Wonder if this is a risk for being exploited somehow to take photos of people's desktops


I wrote a simple HTML and JS to test if that's possible: Load this GIF, then draw it into a canvas using drawImage[1], then read the canvas content with getImageData. Luckily it returns an array of zeros, so it at least not trivially exploitable.

[1] https://developer.mozilla.org/en-US/docs/Web/API/CanvasRende... [2] https://developer.mozilla.org/en-US/docs/Web/API/CanvasRende...


The browser is rendering that region of its window as transparent, and the display compositor is obliging by showing the layers below the browser window. The browser window itself doesn't know anything about the pixels of the layers below it. So anything that looks at the browser window, like canvas.getImageData will not return those pixels.

However screen-sharing API like getDisplayMedia() will screencopy at the compositor level, so they will include those pixels depending on what you choose to share.


Same here on Arch with Firefox (perhaps due to the fact that I'm using a Wayland compositor?). It was quite surprising!


I see the desktop background through it on Archlinux with Firefox, using X with cinnamon. Even if there's another window behind, it shows the desktop background wallpaper


I suppose that the graphical library simply copies the raw values to output pixels without interpreting them (as it should). In true 256 color mode (on old systems, before the effective deprecation of all the color conversion and matching routines) that would probably use the current palette. In the early 90s, if you had a lot of GIFs sharing the same palette, and knew that the program displaying them had already set it once, you could skip implementing all the palette handling.


Haha - it punctured your Firefox window!


Here (Firefox on Manjaro X11) I get a HOM effect inside the square while scrolling and with whatever window was previously on top of the square. Sometimes it also renders a little bit of what was behind the window too.. very curious indeed.


Same here with Firefox on GNOME on Arch.

I do have amusement when the author says it's a black square on every renderer he's tried, but we trivially trigger something else :)

Seems like he's on Mac OS X and so I guess it's down to platform quirks.


Same here, FF on Ubuntu, it's like a rectangle was cut out of the browser window.


Very interesting discovery. Can you share a screenshot?


It's nothing special. Relevant part: https://snipboard.io/Izntmp.jpg


Maybe this screenshot is clearer since it shows the full desktop (Debian, KDE, X): https://i.imgur.com/Aqy3Twm.png.


Okay this had me giggling like an idiot. That's a hell of a bug.


Curious if it's exploitable.


I think JS can only read pixels from the screen within a Canvas, which likely would just return the canvas colors not the background. Maybe there's some complicated ninja social engineering you could do using this, but I doubt it.


Once upon a time i wrote some code to display metadata for gif files that were uploaded to wikipedia.

My favorite part of gif is the hack to embed XMP metadata into gif files. XMP is supposed to be valid xml (it is adobe's rdf based image metadata standard), and should be readable even by format unaware readers. However gif metadata is supposed to be split into (up to) 255 byte blocks where you do 1 byte length, followed by that many bytes of data, another length byte + data, until you terminate with a null byte for a zero length data segment.

This of course is incompatible with making valid xml. However nulls are invalid in xml, so what the spec makers did instead was to ignore these length bytes, just put the xml in without changing it, but end the section with <FF>, <FE>, .... <01>, <00> as a sort of NOP slide-esque thing, in order to make sure everything is well formed acording to the gif standard. If your parsing the file like a normal gif eventually you will jump into the end segment, and everything will be well formed. Its just such an interesting hack to meet all requirements.

Of course, i'm not sure anyone actually creates gif files with metadata so may be a bit moot in practice.


I actually wrote a GIF decoder over the xmas break (in C for 16 bit DOS for a game project I'm working on). In itself it's not to difficult. Once you've figured out the algorithm of when to add a new phrase to the dictionary and how to extract a code from the bit stream, it's pretty straight forward.

I had a massive bug however and I couldn't for the life of me figure out the issue up until two weeks ago.

Turns out, once you've reached a code size of 12 bits, I was "assuming" you should reset to the root code size, however, you should not. Instead of resetting, you should ignore either increasing or resetting the code size, but just keep reading 12 bits codes from the bit stream because from that point on, all codes read from the stream will be in the dictionary. The encoder will have inserted a Clear Code to reset and start from scratch.

It was a difficult thing to debug but once I wrapped my head around it, it made total sense. It was very satisfying to throw a large collection of GIFs at my decoder and see them being displayed.


Reminds me of how FRACTINT would put the fractal formulae into GIFs.

You can load a GIF in it that it has previously saved and re-render the Fractal.


I had no idea it did that. I spent way too much time zooming in on those. Wasn't FRACTINT from the same group that made GIF or was it a different forum?


GIF was defined by CompuServe in 1987 and extended in 1989. FRACTINT was written by an independent programmer.


Heh. With regards to the "longest PNG in existence"

It's only 65536x1.

This hedgewars map is 262144x512 https://m8y.org/hw/WTF/Maps/WTF/

Limitations on ginormous hedgewars maps being documented here: https://hedgewars.org/kb/PresetMaps#Basic_files

(an additional limitation encountered in Hedgewars was SDL being incapable of painting very long or very tall maps - this was worked around by removing the SDL function and using direct byte copy)


Online articles about GIF were junk for the longest time - folks would reverse-engineer the 'header' and call out all the fields they found.

Unfortunately a GIF is a set of tagged records. They can theoretically occur in any order. But these amateur decoders would pick out fields where they 'knew' they would be.

Upshot: different tools have very different success rates decoding anything even slightly off-normal. So even though a GIF is a set of tagged records, you write them that way at your peril.

In other news, I wrote a GIF renderer that added features like sprites, animation and scripting. It was for a PocketPC game called Lexicon. Fun!


I remember downloading the BOB_89A.GIF file from a local BBS eons ago. I've been trying to find it again for the inevitable pronunciation war threads. Now it looks like the text overlay component that was part of the spec is hardly supported anymore.


Thank you for that filename, I had tried to dig up what it was, but my memory on where I got it, much less the name, was too fuzzy to remember.

For those that are curious, here's what it looks like when viewed with an era-appropriate viewer like CompuShow:

https://imgur.com/a/YUrodHD


Yeah, I guess BOB_89A.GIF is the CANYON.MID of that era.

I'd completely forgotten about it, but remembered it as soon as I saw it. Crazy to think that was "full screen" and seemed hi-res.


Once was full-screen entertainment, now is a favicon...


Funny enough, on Firefox for Android, I can't download BOB_89A.GIF. I can view it ok, but saving it fails.


Really enjoyed the majority of this article. I'm ignorant as to whether @fagnerbrack is the author of the article, but I would respectfully ask that the author consider replacing the "popular test" gif with one that the subject hasn't asked to be removed.


Amazing article! Posts like that is one of a few reasons I check HN



> That’s a little boring, but I’m not sure what I expected.

I thought the browser was gonna use some sort of default color table. Or generate a new table with random colors every time it loaded the image. Wouldn't that be fun? Maybe even let me save the generated color table hard-coded into a new GIF.


It would be nice if GIF were written in all caps instead of in lowercase.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: