Fossil SCM
Markdown enhancement (after [forum: /forumpost/938896d37da30394|forum post 938896d37da30394] and follow-ups) in which <html>...</html> that is preceded and followed by blank lines disables all markdown processing and just returns raw HTML text. The <html> and its end-tag are removed. Removal of "dangerous" HTML is handled in a later pass, so the results should still be safe.
Commit
1e919d601f774fdbf3ac4ddcd8658429480396824210dfdc2d5585eb8521e5f2
Parent
48c06b0a134b4b3…
1 file changed
+15
-3
+15
-3
| --- src/markdown.c | ||
| +++ src/markdown.c | ||
| @@ -178,10 +178,11 @@ | ||
| 178 | 178 | ** When these HTML tags are separated from other text by newlines |
| 179 | 179 | ** then they are rendered verbatim. Their content is not interpreted |
| 180 | 180 | ** in any way. |
| 181 | 181 | */ |
| 182 | 182 | static const struct html_tag block_tags[] = { |
| 183 | + { "html", 4 }, | |
| 183 | 184 | { "pre", 3 }, |
| 184 | 185 | { "script", 6 }, |
| 185 | 186 | }; |
| 186 | 187 | |
| 187 | 188 | |
| @@ -251,12 +252,16 @@ | ||
| 251 | 252 | |
| 252 | 253 | /* cmp_html_tag -- comparison function for bsearch() (stolen from discount) */ |
| 253 | 254 | static int cmp_html_tag(const void *a, const void *b){ |
| 254 | 255 | const struct html_tag *hta = a; |
| 255 | 256 | const struct html_tag *htb = b; |
| 256 | - if( hta->size!=htb->size ) return hta->size-htb->size; | |
| 257 | - return fossil_strnicmp(hta->text, htb->text, hta->size); | |
| 257 | + int sz = hta->size; | |
| 258 | + int c; | |
| 259 | + if( htb->size<sz ) sz = htb->size; | |
| 260 | + c = fossil_strnicmp(hta->text, htb->text, sz); | |
| 261 | + if( c==0 ) c = hta->size - htb->size; | |
| 262 | + return c; | |
| 258 | 263 | } |
| 259 | 264 | |
| 260 | 265 | |
| 261 | 266 | /* find_block_tag -- returns the current block tag */ |
| 262 | 267 | static const struct html_tag *find_block_tag(const char *data, size_t size){ |
| @@ -1796,11 +1801,18 @@ | ||
| 1796 | 1801 | } |
| 1797 | 1802 | } |
| 1798 | 1803 | if( !found ) return 0; |
| 1799 | 1804 | |
| 1800 | 1805 | /* the end of the block has been found */ |
| 1801 | - blob_init(&work, data, i); | |
| 1806 | + if( strcmp(curtag->text,"html")==0 ){ | |
| 1807 | + /* Omit <html> tags */ | |
| 1808 | + enum mkd_autolink dummy; | |
| 1809 | + int k = tag_length(data, size, &dummy); | |
| 1810 | + blob_init(&work, data+k, i-(j+k)); | |
| 1811 | + }else{ | |
| 1812 | + blob_init(&work, data, i); | |
| 1813 | + } | |
| 1802 | 1814 | if( rndr->make.blockhtml ){ |
| 1803 | 1815 | rndr->make.blockhtml(ob, &work, rndr->make.opaque); |
| 1804 | 1816 | } |
| 1805 | 1817 | return i; |
| 1806 | 1818 | } |
| 1807 | 1819 |
| --- src/markdown.c | |
| +++ src/markdown.c | |
| @@ -178,10 +178,11 @@ | |
| 178 | ** When these HTML tags are separated from other text by newlines |
| 179 | ** then they are rendered verbatim. Their content is not interpreted |
| 180 | ** in any way. |
| 181 | */ |
| 182 | static const struct html_tag block_tags[] = { |
| 183 | { "pre", 3 }, |
| 184 | { "script", 6 }, |
| 185 | }; |
| 186 | |
| 187 | |
| @@ -251,12 +252,16 @@ | |
| 251 | |
| 252 | /* cmp_html_tag -- comparison function for bsearch() (stolen from discount) */ |
| 253 | static int cmp_html_tag(const void *a, const void *b){ |
| 254 | const struct html_tag *hta = a; |
| 255 | const struct html_tag *htb = b; |
| 256 | if( hta->size!=htb->size ) return hta->size-htb->size; |
| 257 | return fossil_strnicmp(hta->text, htb->text, hta->size); |
| 258 | } |
| 259 | |
| 260 | |
| 261 | /* find_block_tag -- returns the current block tag */ |
| 262 | static const struct html_tag *find_block_tag(const char *data, size_t size){ |
| @@ -1796,11 +1801,18 @@ | |
| 1796 | } |
| 1797 | } |
| 1798 | if( !found ) return 0; |
| 1799 | |
| 1800 | /* the end of the block has been found */ |
| 1801 | blob_init(&work, data, i); |
| 1802 | if( rndr->make.blockhtml ){ |
| 1803 | rndr->make.blockhtml(ob, &work, rndr->make.opaque); |
| 1804 | } |
| 1805 | return i; |
| 1806 | } |
| 1807 |
| --- src/markdown.c | |
| +++ src/markdown.c | |
| @@ -178,10 +178,11 @@ | |
| 178 | ** When these HTML tags are separated from other text by newlines |
| 179 | ** then they are rendered verbatim. Their content is not interpreted |
| 180 | ** in any way. |
| 181 | */ |
| 182 | static const struct html_tag block_tags[] = { |
| 183 | { "html", 4 }, |
| 184 | { "pre", 3 }, |
| 185 | { "script", 6 }, |
| 186 | }; |
| 187 | |
| 188 | |
| @@ -251,12 +252,16 @@ | |
| 252 | |
| 253 | /* cmp_html_tag -- comparison function for bsearch() (stolen from discount) */ |
| 254 | static int cmp_html_tag(const void *a, const void *b){ |
| 255 | const struct html_tag *hta = a; |
| 256 | const struct html_tag *htb = b; |
| 257 | int sz = hta->size; |
| 258 | int c; |
| 259 | if( htb->size<sz ) sz = htb->size; |
| 260 | c = fossil_strnicmp(hta->text, htb->text, sz); |
| 261 | if( c==0 ) c = hta->size - htb->size; |
| 262 | return c; |
| 263 | } |
| 264 | |
| 265 | |
| 266 | /* find_block_tag -- returns the current block tag */ |
| 267 | static const struct html_tag *find_block_tag(const char *data, size_t size){ |
| @@ -1796,11 +1801,18 @@ | |
| 1801 | } |
| 1802 | } |
| 1803 | if( !found ) return 0; |
| 1804 | |
| 1805 | /* the end of the block has been found */ |
| 1806 | if( strcmp(curtag->text,"html")==0 ){ |
| 1807 | /* Omit <html> tags */ |
| 1808 | enum mkd_autolink dummy; |
| 1809 | int k = tag_length(data, size, &dummy); |
| 1810 | blob_init(&work, data+k, i-(j+k)); |
| 1811 | }else{ |
| 1812 | blob_init(&work, data, i); |
| 1813 | } |
| 1814 | if( rndr->make.blockhtml ){ |
| 1815 | rndr->make.blockhtml(ob, &work, rndr->make.opaque); |
| 1816 | } |
| 1817 | return i; |
| 1818 | } |
| 1819 |