mdiep / MMMarkdown

An Objective-C framework for converting Markdown to HTML.
MIT License
1.25k stars 168 forks source link

MMScanner assertion is firing unexpectedly and crashing app #47

Closed iosdev-republicofapps closed 9 years ago

iosdev-republicofapps commented 9 years ago

Hi,

I'm interactively parsing Markdown from an NSTextView as the user types. Sometimes, rarely, I get an app crash (in debug mode) with the assertion in MMScanner.initWithString:lineRanges firing:

- (id)initWithString:(NSString *)aString lineRanges:(NSArray *)theLineRanges
{
    NSParameterAssert(theLineRanges.count > 0);

Here's the stack trace:

2015-01-15 00:10:47.981 MarkdownTestMM[28490:1393172] Invalid parameter not satisfying: theLineRanges.count > 0
2015-01-15 00:10:47.982 MarkdownTestMM[28490:1393172] (
    0   CoreFoundation                      0x00007fff8e10c64c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff84b506de objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff8e10c42a +[NSException raise:format:arguments:] + 106
    3   Foundation                          0x00007fff8c8305b9 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195
    4   MarkdownTestMM                      0x0000000100013c9a -[MMScanner initWithString:lineRanges:] + 298
    5   MarkdownTestMM                      0x0000000100013b2b +[MMScanner scannerWithString:lineRanges:] + 139
    6   MarkdownTestMM                      0x0000000100011e92 -[MMParser _parseParagraphWithScanner:] + 1730
    7   MarkdownTestMM                      0x000000010000c3b6 -[MMParser _parseBlockElementWithScanner:] + 1894
    8   MarkdownTestMM                      0x000000010000bb1f -[MMParser _parseElementsWithScanner:] + 127
    9   MarkdownTestMM                      0x000000010000ad14 -[MMParser parseMarkdown:error:] + 212
    10  MarkdownTestMM                      0x000000010000aa4e +[MMMarkdown HTMLStringWithMarkdown:extensions:fromSelector:error:] + 510
    11  MarkdownTestMM                      0x000000010000a817 +[MMMarkdown HTMLStringWithMarkdown:extensions:error:] + 103
    12  MarkdownTestMM                      0x000000010000413b __42-[Document parseMarkdown:success:failure:]_block_invoke + 91
    13  libdispatch.dylib                   0x000000010005c2bb _dispatch_call_block_and_release + 12
    14  libdispatch.dylib                   0x0000000100056d43 _dispatch_client_callout + 8
    15  libdispatch.dylib                   0x000000010005afb3 _dispatch_queue_drain + 1804
    16  libdispatch.dylib                   0x000000010005cfc0 _dispatch_queue_invoke + 223
    17  libdispatch.dylib                   0x0000000100059f5e _dispatch_root_queue_drain + 666
    18  libdispatch.dylib                   0x000000010006bcd0 _dispatch_worker_thread3 + 106
    19  libsystem_pthread.dylib             0x00007fff8f5146cb _pthread_wqthread + 729
    20  libsystem_pthread.dylib             0x00007fff8f5124a1 start_wqthread + 13
)
2015-01-15 00:10:47.983 MarkdownTestMM[28490:1393172] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: theLineRanges.count > 0'

I'm invoking the parsing as follows:

NSString *markdown = ...;
NSError * __autoreleasing error;
NSString *htmlOutput = [MMMarkdown HTMLStringWithMarkdown:markdown extensions:MMMarkdownExtensionsTables|MMMarkdownExtensionsFencedCodeBlocks|MMMarkdownExtensionsUnderscoresInWords error:&error];

Here's some sample input that crashes it:

Here is some other stuff.
dd

 #H    eisa Headline

Here is some text.

##  ddd

Here is that

# e is ale d

Here is some math:     

>\`sum_(n=0)^oo x^n\`

This input doesn't crash it every time, but often it does. Well, this is the last input I logged before it crashed, so the actual input might have been off by 1 character +/-.

Any ideas?

I guess the assertion is firing because some kind of logical assumption is not holding in MMParser, but I feel like MMParser should be able to handle whatever input it gets, even if it's potentially invalid markdown.

I'm worried about what this is going to mean in a release build where the assertion won't fire - will some more serious issue cascade and really crash my app or will it just potentially mis-parse the markdown input (that would be OK if temporary and later user typing fixed it).

Sorry, I'm trying to create test case that repos this 100% of the time, but I'm having trouble doing so.

Please let me know how I can help. :-)

iosdev-republicofapps commented 9 years ago

OK, I found a test case which repros the crash every time:

NSString *badInput = @" #H";
NSError * __autoreleasing error;
NSString *htmlOutput = [MMMarkdown HTMLStringWithMarkdown:badInput extensions:MMMarkdownExtensionsTables|MMMarkdownExtensionsFencedCodeBlocks|MMMarkdownExtensionsUnderscoresInWords error:&error];

It appears to be the leading space on the line before the '#'. The input "#H" is fine, no crash. However just adding a leading space to create " #H" causes the assertion to fire and a crash.

The Markdown "spec" (using the term spec lightly :-) ) at http://daringfireball.net/projects/markdown/syntax#header doesn't say that a paragraph can't begin with a '#' it just says that Atx-style headers use 1-6 hash characters at the start of the line, corresponding to header levels 1-6. So that seems to indicate that " #H" is legal Markdown.

Please let me know how else I can help :-), but this test case repros the crash every time.

Thanks again, I'm really like MMMarkdown!

mdiep commented 9 years ago

Thanks for the test case! This should be all fixed up now.

iosdev-republicofapps commented 9 years ago

My pleasure! And thank you so much for fixing it so quickly, that's awesome, I really appreciate it.

Any chance of getting a 0.4.1 or 0.5 release with this fix in it? :-) I took over ownership of the Cocoapods pod spec in the pod specs repo, to help out, so I can update the version there once there's a new release.

mdiep commented 9 years ago

I just created 0.4.1 for this fix.

iosdev-republicofapps commented 9 years ago

Thanks!

I just pushed the 0.4.1 pod spec to Cocoapods.