mdiep / MMMarkdown

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

Scanner hangs in infinite loop on html tag attributes like <p style=" #44

Closed iosdev-republicofapps closed 9 years ago

iosdev-republicofapps commented 9 years ago

Hi,

I'm using MMMarkdown in a custom Markdown editor app. So as the user types, I periodically parse the Markdown every few keystrokes so I can show a live preview of what the parsed Markdown will look like.

Most of the time it works really well and is fast, thanks! :-)

Since Markdown can legally include HTML, the following would be legal Markdown:

<p style="color: red">Hello, world!</p>

However, the MMHTMLParser._parseStringWithScanner method hangs as soon as the user types and the parser attempts to parse the following:

<p style="

It hangs as soon as the " after the = is typed. This will be a common case if the parser is used to parse Markdown interactively or in an editor - it will encounter incomplete HTML like this and it shouldn't get caught in an infinite loop.

I took a look at MMHTMLParser._parseStringWithScanner and the problem seems to be the code:

    while (scanner.nextCharacter != nextChar)
    {
        if (scanner.atEndOfLine)
        {
            [scanner advanceToNextLine];
            continue;
        }

This gets caught in an infinite loop for <p style=". The problem seems to be that it's not advancing the scanner's location.

I made a temporary fix to get past this infinite loop, where I changed the above code to:

    while (scanner.nextCharacter != nextChar)
    {
        if (scanner.atEndOfLine)
        {
            NSUInteger oldScannerLocation = scanner.location;
            [scanner advanceToNextLine];
            if (scanner.location == oldScannerLocation) {
                // Avoid infinite loop for string: <p style="
                break;
            } else {
                continue;
            }
        }

In this case, the loop is broken if the scanner's location fails to advance. This is a hacky solution as I didn't have time to go over the whole logic flow. I feel my hack is maybe papering over the problem and that there's a better solution, but I'm not sure ... Any tips?

I'd be happy to help - please let me know how I can help. But I just wanted to let you know about this.

Note that if I paste in the complete html, the parser doesn't hang. This works fine:

<p style="color: red">Hello, world!</p>

It only hangs for partial HTML like

<p style="

Note: This is not specific to the p tag or the style attribute. It happens for other tags and other attributes.

I think it would be fine for the parser to return an error for "invalid markdown" in this case, I don't think it needs to try valiantly to recover or repair this incomplete html. But it shouldn't get caught in an infinite loop ...

Best and thanks again, I really like MMMarkdown!

mdiep commented 9 years ago

Thanks for filing an issue! I'll try to get to this in the next few days.

iosdev-republicofapps commented 9 years ago

You're welcome and no huge rush as I have a temporary hacky fix for now. Thanks. :-)

iosdev-republicofapps commented 9 years ago

Thanks!