<-- click to return

Markdown Mayhem in Disco-town.

Joking around on Discord about how old one of our friend is, we stumbled upon a bug. If you had the year represented as a number and a dot after it (like 1784.) Discord would do something interesting: the message would get rendered wrong.
What's going on?

What is Markdown?

To fully understand what's going on, we must understand what markdown is. It's a lightweight markup language, designed for formatting text online. You might've seen it in use with Github Readmes. You can create headings, emphasize text through bolding or italic styling, you can create lists, hyperlinks.. sometimes more. Discord introduced this feature in the Spring of 2023, enhancing the text formatting capabilities of it's platform.

The Rendering Quirk.

Within markdown, it's possible to create ordered lists that start from a specific number. For example, typing "1. First index" generates an ordered list in Markdown, beginning from 1. Smartest of you have already realised this seems familiar. When rendered on Discord, the HTML generated looks like this:

And the application renders the above like this:

Huh, that's interesting -- it seems like the message is flowing outside of bounds.. what is going on?

The bugs origins.

So what's the issue with rendering? We can see that in the HTML, markdown is marked as "::marker". This is called a "selector", and it creates a pseudo-element to apply CSS specifically to this marker. There lies our issue: within the CSS. The CSS causes the message to start from further left than it should. What's interesting is, that the first character of the ordered lists index begins where the message normally begins: the CSS pushes the message left 1 character per 1 character in the "ordinal number."

How far left can we go?

.. and I'm not here to discuss politics. Let's see how many 3's we can fit into 1337. before something happens:

The limit seems to be at: 13333333337, afterwhich Discord goes ahead and makes it start from 1 again. Biggest number we can insert before it doing the same seems to be 2147483647, which unsurprisingly is the maximum size of a 32-bit signed integer. Not really useful knowledge to us, but this means Discord either stores or handles the ordinal numbers as integers, and allows them to be only the size of a 32-bit int. Anything bigger gets turned to -> 1.

How far can we push the bug?

Here we get to the fun part: Chaining markdown. With lists -- be they ordered or not -- you can use Markdown inside the list element too. Meaning, you guessed it, we can create lists inside of lists. So if the list number gets pushed to the left, what happens if we have two of them?

They overlap! How fun! So how many can we overlap? Unfortunately with lists the number is 11. Here's what it looks like, using the max integer as the value:

What about other markdown? What else can we add to the mix? Let's see headers. We can append "#" at the beginning, to make the whole message one big heading. Or we can use ">" to make block quotes. Here we see some of the bug manifest itself again, as the list pushes "through" the line:

Ok cool bug, but will Discord fix it?

Maybe. Maybe not. When we stumbled upon it, after playing around with it trying to get something to break, we took a look at Twitter. Has anyone mentioned the bug before? I only found a handful of tweets regarding the Markdown bug. It's interesting and fun to play with, but there isn't much real impact, apart from Flexxing your master h4ck3r skills to your friends. I would not be surprised if it was down last on Discords list of things to fix. It's interesting it hasn't spread much, this trick, though after mentioning it to friends I did see it go around some servers a little bit. What I did not have the interest to find out was why on Mobile it didn't happen. On mobile it would only render as 50Message -- and continue from there onwards. Perhaps CSS on mobile is significantly different..? Who knows.

Bonus Bug!

Combine everything learnt here with a ghost ping, and you can have some fun!

Thanks for reading, and I hope you learned something!