]> granicus.if.org Git - multimarkdown/commitdiff
FIXED: Improve reliability or link scanner
authorFletcher T. Penney <fletcher@fletcherpenney.net>
Sun, 12 Feb 2017 19:56:03 +0000 (14:56 -0500)
committerFletcher T. Penney <fletcher@fletcherpenney.net>
Sun, 12 Feb 2017 19:56:03 +0000 (14:56 -0500)
src/html.c
src/latex.c
src/scanners.c
src/scanners.h
src/scanners.re
src/writer.c
src/writer.h
tests/MMD6Tests/Inline Links.html
tests/MMD6Tests/Inline Links.htmlc
tests/MMD6Tests/Inline Links.text

index 6d08ee7e7292f8f89e2ecb1a2265808774d1ebab..689ff8df1f2aa006c18bc294a3ff15a08b949f11 100644 (file)
@@ -943,9 +943,7 @@ void mmd_export_token_html(DString * out, const char * source, token * t, size_t
                        print("</code>");
                        break;
                case PAIR_ANGLE:
-                       temp_token = t;
-
-                       temp_char = url_accept(source, &temp_token, true);
+                       temp_char = url_accept(source, t->start + 1, t->len - 2, NULL, true);
 
                        if (temp_char) {
                                if (scan_email(temp_char))
index 457e91319fde4ecf1219f0255da536c4b9af24a4..1d04073eec095e1af524c3b0367cd1ed2397dc97 100644 (file)
@@ -660,9 +660,7 @@ void mmd_export_token_latex(DString * out, const char * source, token * t, scrat
                        print_char(' ');
                        break;
                case PAIR_ANGLE:
-                       temp_token = t;
-
-                       temp_char = url_accept(source, &temp_token, true);
+                       temp_char = url_accept(source, t->start + 1, t->len - 2, NULL, true);
 
                        if (temp_char) {
                                if (scan_email(temp_char)) {
index 15ddd0cbfe7e13615be16a492f2c0ffc7c6bf55d..9284b6c5d540c2fd2c336d13896430c98f95f277 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.14.3 on Sat Feb 11 13:20:22 2017 */
+/* Generated by re2c 0.14.3 on Sun Feb 12 13:52:25 2017 */
 /**
 
        MultiMarkdown 6 -- Lightweight markup processor to produce HTML, LaTeX, and more.
@@ -9468,7 +9468,7 @@ yy730:
 }
 
 
-size_t scan_setext(const char * c) {
+size_t scan_title(const char * c) {
        const char * marker = NULL;
        const char * start = c;
 
@@ -9478,9 +9478,9 @@ size_t scan_setext(const char * c) {
        yych = *c;
        switch (yych) {
        case '\n':      goto yy733;
-       case ' ':       goto yy734;
-       case '-':       goto yy736;
-       case '=':       goto yy735;
+       case '"':       goto yy734;
+       case '\'':      goto yy735;
+       case '(':       goto yy736;
        default:        goto yy737;
        }
 yy733:
@@ -9488,22 +9488,26 @@ yy733:
 yy734:
        yych = *(marker = ++c);
        switch (yych) {
-       case ' ':       goto yy749;
-       case '-':       goto yy750;
-       case '=':       goto yy751;
-       default:        goto yy733;
+       case 0x00:
+       case '\n':
+       case '\r':      goto yy733;
+       default:        goto yy746;
        }
 yy735:
        yych = *(marker = ++c);
        switch (yych) {
-       case '=':       goto yy744;
-       default:        goto yy733;
+       case 0x00:
+       case '\n':
+       case '\r':      goto yy733;
+       default:        goto yy744;
        }
 yy736:
        yych = *(marker = ++c);
        switch (yych) {
-       case '-':       goto yy738;
-       default:        goto yy733;
+       case 0x00:
+       case '\n':
+       case '\r':      goto yy733;
+       default:        goto yy739;
        }
 yy737:
        yych = *++c;
@@ -9511,72 +9515,155 @@ yy737:
 yy738:
        ++c;
        yych = *c;
+yy739:
        switch (yych) {
        case 0x00:
-       case '\n':      goto yy741;
-       case '\r':      goto yy743;
-       case '-':       goto yy738;
-       default:        goto yy740;
+       case '\n':
+       case '\r':      goto yy740;
+       case ')':       goto yy741;
+       default:        goto yy738;
        }
 yy740:
        c = marker;
        goto yy733;
 yy741:
        ++c;
-yy742:
        { return (size_t)( c - start ); }
 yy743:
+       ++c;
+       yych = *c;
+yy744:
+       switch (yych) {
+       case 0x00:
+       case '\n':
+       case '\r':      goto yy740;
+       case '\'':      goto yy741;
+       default:        goto yy743;
+       }
+yy745:
+       ++c;
+       yych = *c;
+yy746:
+       switch (yych) {
+       case 0x00:
+       case '\n':
+       case '\r':      goto yy740;
+       case '"':       goto yy741;
+       default:        goto yy745;
+       }
+}
+       
+}
+
+size_t scan_setext(const char * c) {
+       const char * marker = NULL;
+       const char * start = c;
+
+
+{
+       char yych;
+       yych = *c;
+       switch (yych) {
+       case '\n':      goto yy749;
+       case ' ':       goto yy750;
+       case '-':       goto yy752;
+       case '=':       goto yy751;
+       default:        goto yy753;
+       }
+yy749:
+       { return 0; }
+yy750:
+       yych = *(marker = ++c);
+       switch (yych) {
+       case ' ':       goto yy765;
+       case '-':       goto yy766;
+       case '=':       goto yy767;
+       default:        goto yy749;
+       }
+yy751:
+       yych = *(marker = ++c);
+       switch (yych) {
+       case '=':       goto yy760;
+       default:        goto yy749;
+       }
+yy752:
+       yych = *(marker = ++c);
+       switch (yych) {
+       case '-':       goto yy754;
+       default:        goto yy749;
+       }
+yy753:
        yych = *++c;
+       goto yy749;
+yy754:
+       ++c;
+       yych = *c;
        switch (yych) {
-       case '\n':      goto yy741;
-       default:        goto yy742;
+       case 0x00:
+       case '\n':      goto yy757;
+       case '\r':      goto yy759;
+       case '-':       goto yy754;
+       default:        goto yy756;
        }
-yy744:
+yy756:
+       c = marker;
+       goto yy749;
+yy757:
+       ++c;
+yy758:
+       { return (size_t)( c - start ); }
+yy759:
+       yych = *++c;
+       switch (yych) {
+       case '\n':      goto yy757;
+       default:        goto yy758;
+       }
+yy760:
        ++c;
        yych = *c;
        switch (yych) {
        case 0x00:
-       case '\n':      goto yy746;
-       case '\r':      goto yy748;
-       case '=':       goto yy744;
-       default:        goto yy740;
+       case '\n':      goto yy762;
+       case '\r':      goto yy764;
+       case '=':       goto yy760;
+       default:        goto yy756;
        }
-yy746:
+yy762:
        ++c;
-yy747:
+yy763:
        { return (size_t)( c - start ); }
-yy748:
+yy764:
        yych = *++c;
        switch (yych) {
-       case '\n':      goto yy746;
-       default:        goto yy747;
+       case '\n':      goto yy762;
+       default:        goto yy763;
        }
-yy749:
+yy765:
        yych = *++c;
        switch (yych) {
-       case ' ':       goto yy752;
-       case '-':       goto yy750;
-       case '=':       goto yy751;
-       default:        goto yy740;
+       case ' ':       goto yy768;
+       case '-':       goto yy766;
+       case '=':       goto yy767;
+       default:        goto yy756;
        }
-yy750:
+yy766:
        yych = *++c;
        switch (yych) {
-       case '-':       goto yy738;
-       default:        goto yy740;
+       case '-':       goto yy754;
+       default:        goto yy756;
        }
-yy751:
+yy767:
        yych = *++c;
        switch (yych) {
-       case '=':       goto yy744;
-       default:        goto yy740;
+       case '=':       goto yy760;
+       default:        goto yy756;
        }
-yy752:
+yy768:
        ++c;
        switch ((yych = *c)) {
-       case '-':       goto yy750;
-       case '=':       goto yy751;
-       default:        goto yy740;
+       case '-':       goto yy766;
+       case '=':       goto yy767;
+       default:        goto yy756;
        }
 }
        
index d952f7250b6340c111216c08ff208af904d7a9a0..c42ecb0490661f40fbfafe1801182d0000036b10 100644 (file)
@@ -90,6 +90,7 @@ size_t scan_ref_link_no_attributes(const char * c);
 size_t scan_setext(const char * c);
 size_t scan_spnl(const char * c);
 size_t scan_table_separator(const char * c);
+size_t scan_title(const char * c);
 size_t scan_url(const char * c);
 size_t scan_value(const char * c);
 
index 9f1394c7e4cc35ca4cc31b2c2a414247e27c3f22..8306b16e3fac9224a5f4681ba1fd18b66a9fb9d5 100644 (file)
@@ -402,6 +402,16 @@ size_t scan_destination(const char * c) {
 }
 
 
+size_t scan_title(const char * c) {
+       const char * marker = NULL;
+       const char * start = c;
+
+/*!re2c
+       title   { return (size_t)( c - start ); }
+       .?                      { return 0; }
+*/     
+}
+
 size_t scan_setext(const char * c) {
        const char * marker = NULL;
        const char * start = c;
index 276e957754966a151d81f28244065be9d327b14a..f39eaae47dc4cf69c26f9ccb900e9e4b3f1234dd 100644 (file)
@@ -722,90 +722,80 @@ char * destination_accept(const char * source, token ** remainder, bool validate
 }
 
 
-char * url_accept(const char * source, token ** remainder, bool validate) {
+char * url_accept(const char * source, size_t start, size_t max_len, size_t * end_pos, bool validate) {
        char * url = NULL;
        char * clean = NULL;
-       token * t = NULL;
-       token * first = NULL;
-       token * last = NULL;
+       size_t scan_len;
 
-       switch ((*remainder)->type) {
-               case PAIR_PAREN:
-               case PAIR_ANGLE:
-               case PAIR_QUOTE_SINGLE:
-               case PAIR_QUOTE_DOUBLE:
-                       t = token_chain_accept_multiple(remainder, 2, PAIR_ANGLE, PAIR_PAREN);
-                       url = text_inside_pair(source, t);
-                       break;
-               case SLASH:
-               case TEXT_PLAIN:
-                       first = *remainder;
-                       
-                       // Grab parts for URL
-                       while (token_chain_accept_multiple(remainder, 7, AMPERSAND, COLON, EQUAL, SLASH, TEXT_PERIOD, TEXT_PLAIN, UL));
+       scan_len = scan_destination(&source[start]);
 
-                       last = (*remainder)->prev;
+       if (scan_len) {
+               if (scan_len > max_len)
+                       scan_len = max_len;
 
-                       // Is there a space in a URL concatenated with a title or attribute?
-                       // e.g. [foo]: http://foo.bar/ class="foo"
-                       // Since only one space between URL and class, they are joined.
+               if (end_pos)
+                       *end_pos = start + scan_len;
 
-                       if (last->type == TEXT_PLAIN) {
-                               // Trim leading whitespace
-                               token_trim_leading_whitespace(last, source);
-                               token_split_on_char(last, source, ' ');
-                               *remainder = last->next;
-                       }
+               // Is this <foo>?
+               if ((source[start] == '<') &&
+                       (source[start + scan_len - 1] == '>')) {
+                       // Strip '<' and '>'
+                       start++;
+                       scan_len -= 2;
+               }
 
-                       url = strndup(&source[first->start], last->start + last->len - first->start);
-                       break;
-       }
+               url = strndup(&source[start], scan_len);
 
-       // Is this a valid URL?
-       clean = clean_string(url, false);
-       
-       if (validate && !validate_url(clean)) {
-               free(clean);
-               clean = NULL;
+               clean = clean_string(url, false);
+
+               if (validate && !validate_url(clean)) {
+                       free(clean);
+                       clean = NULL;
+               }
+
+               free(url);
        }
 
-       free(url);
        return clean;
 }
 
 
 /// Extract url string from `(foo)` or `(<foo>)` or `(foo "bar")`
 void extract_from_paren(token * paren, const char * source, char ** url, char ** title, char ** attributes) {
-       token * t;
+   size_t scan_len;
+    size_t pos = paren->child->next->start;
+    
+    
        size_t attr_len;
 
-       token * remainder = paren->child->next;
+       // Skip whitespace
+       while (char_is_whitespace(source[pos]))
+               pos++;
 
-       if (remainder) {
-               // Skip whitespace
-               whitespace_accept(&remainder);
+       // Grab URL
+       *url = url_accept(source, pos, paren->start + paren->len - 1 - pos, &pos, false);
 
-               // Grab URL
-               *url = url_accept(source, &remainder, false);
+       // Skip whitespace
+       while (char_is_whitespace(source[pos]))
+               pos++;
 
-               // Skip whitespace
-               whitespace_accept(&remainder);
+       // Grab title, if present
+       scan_len = scan_title(&source[pos]);
 
-               // Grab title, if present
-               t = token_chain_accept_multiple(&remainder, 3, PAIR_QUOTE_DOUBLE, PAIR_QUOTE_SINGLE, PAIR_PAREN);
+       if (scan_len) {
+               *title = strndup(&source[pos + 1], scan_len - 2);
+               pos += scan_len;
+       }
 
-               if (t) {
-                       *title = text_inside_pair(source, t);
-               }
+       // Skip whitespace
+       while (char_is_whitespace(source[pos]))
+               pos++;
 
-               // Grab attributes, if present
-               if (t) {
-                       attr_len = scan_attributes(&source[t->start + t->len]);
-                       
-                       if (attr_len) {
-                               *attributes = strndup(&source[t->start + t->len], attr_len);
-                       }
-               }
+       // Grab attributes, if present
+       attr_len = scan_attributes(&source[pos]);
+       
+       if (attr_len) {
+               *attributes = strndup(&source[pos], attr_len);
        }
 }
 
index 85b92d54f90434bd054f4b3f6c4925e3bd7630df..b20b1f3a241202b5682c8d6f7c53d4939cee9bc6 100644 (file)
@@ -189,7 +189,7 @@ void print_token_raw(DString * out, const char * source, token * t);
 
 void print_token_tree_raw(DString * out, const char * source, token * t);
 
-char * url_accept(const char * source, token ** remainder, bool validate);
+char * url_accept(const char * source, size_t start, size_t max_len, size_t * end_pos, bool validate);
 
 void footnote_from_bracket(const char * source, scratch_pad * scratch, token * t, short * num);
 void citation_from_bracket(const char * source, scratch_pad * scratch, token * t, short * num);
index 664c4b71966e3b422e50b96afce99816e85b4646..6f71ab4ecbf0b78a82d1c53ae2f99d9216fc411e 100644 (file)
 
 <p>[URL and title]
 (/url/file.txt &#8220;<em>title</em>&#8221;).</p>
+
+<p><a href="/url/file.txt" title="title">URL and title</a>.</p>
+
+<p>15</p>
+
+<p><a href="/url/file.txt" title="title">URL and title</a>.</p>
+
+<p><a href="/url/file.txt" title="title">URL and title</a>.</p>
+
+<p><a href="/url/file.txt" title="title">URL and title</a>.</p>
+
+<p><a href="/url/file.txt" title="title">URL and title</a>.</p>
index 302544f52ee04906606c271c946c2b1fbcb10803..239462998f08fcbb39b0bfbea8b688a4ae6b0055 100644 (file)
 
 <p>[URL and title]
 (/url/file.txt &quot;<em>title</em>&quot;).</p>
+
+<p><a href="/url/file.txt" title="title">URL and title</a>.</p>
+
+<p>15</p>
+
+<p><a href="/url/file.txt" title="title">URL and title</a>.</p>
+
+<p><a href="/url/file.txt" title="title">URL and title</a>.</p>
+
+<p><a href="/url/file.txt" title="title">URL and title</a>.</p>
+
+<p><a href="/url/file.txt" title="title">URL and title</a>.</p>
index a6a4095ce70ec48d4d618c7db2119ea3f0ec2d9b..16d4d38985265ae9c9e40d2f0757c6edc4c6aacc 100644 (file)
@@ -30,3 +30,15 @@ Just a [URL](http://url/file.txt).
 
 [URL and title]
 (/url/file.txt "*title*").
+
+[URL and title]( /url/file.txt "title").
+
+15
+
+[URL and title](    /url/file.txt "title").
+
+[URL and title](</url/file.txt> "title").
+
+[URL and title]( </url/file.txt> "title").
+
+[URL and title](  </url/file.txt> "title").