Fossil SCM

Update the HTML safeing mechanism so that it does the entire Markdown output all at once. In this way it is better able to cope with block markup that spans multiple paragraphs.

drh 2020-06-02 17:38 trunk
Commit 382f3731ee65dfd0ac5a9a39e725d6af11c2a3b242781cf7bcd869ad3a4866d8
+1 -1
--- src/browse.c
+++ src/browse.c
@@ -390,11 +390,11 @@
390390
@ </iframe>
391391
}else{
392392
Blob content;
393393
const char *zMime = mimetype_from_name(zName);
394394
content_get(rid, &content);
395
- wiki_render_by_mimetype(&content, zMime);
395
+ wiki_render_by_mimetype(&content, zMime, 0);
396396
}
397397
}
398398
}
399399
db_finalize(&q);
400400
style_footer();
401401
--- src/browse.c
+++ src/browse.c
@@ -390,11 +390,11 @@
390 @ </iframe>
391 }else{
392 Blob content;
393 const char *zMime = mimetype_from_name(zName);
394 content_get(rid, &content);
395 wiki_render_by_mimetype(&content, zMime);
396 }
397 }
398 }
399 db_finalize(&q);
400 style_footer();
401
--- src/browse.c
+++ src/browse.c
@@ -390,11 +390,11 @@
390 @ </iframe>
391 }else{
392 Blob content;
393 const char *zMime = mimetype_from_name(zName);
394 content_get(rid, &content);
395 wiki_render_by_mimetype(&content, zMime, 0);
396 }
397 }
398 }
399 db_finalize(&q);
400 style_footer();
401
+1 -1
--- src/event.c
+++ src/event.c
@@ -508,11 +508,11 @@
508508
@ </blockquote>
509509
@ <p><b>Page content preview:</b><p>
510510
@ <blockquote>
511511
blob_init(&event, 0, 0);
512512
blob_append(&event, zBody, -1);
513
- wiki_render_by_mimetype(&event, zMimetype);
513
+ wiki_render_by_mimetype(&event, zMimetype, 0);
514514
@ </blockquote><hr />
515515
blob_reset(&event);
516516
}
517517
for(n=2, z=zBody; z[0]; z++){
518518
if( z[0]=='\n' ) n++;
519519
--- src/event.c
+++ src/event.c
@@ -508,11 +508,11 @@
508 @ </blockquote>
509 @ <p><b>Page content preview:</b><p>
510 @ <blockquote>
511 blob_init(&event, 0, 0);
512 blob_append(&event, zBody, -1);
513 wiki_render_by_mimetype(&event, zMimetype);
514 @ </blockquote><hr />
515 blob_reset(&event);
516 }
517 for(n=2, z=zBody; z[0]; z++){
518 if( z[0]=='\n' ) n++;
519
--- src/event.c
+++ src/event.c
@@ -508,11 +508,11 @@
508 @ </blockquote>
509 @ <p><b>Page content preview:</b><p>
510 @ <blockquote>
511 blob_init(&event, 0, 0);
512 blob_append(&event, zBody, -1);
513 wiki_render_by_mimetype(&event, zMimetype, 0);
514 @ </blockquote><hr />
515 blob_reset(&event);
516 }
517 for(n=2, z=zBody; z[0]; z++){
518 if( z[0]=='\n' ) n++;
519
+1 -1
--- src/fileedit.c
+++ src/fileedit.c
@@ -976,11 +976,11 @@
976976
case FE_RENDER_HTML_INLINE:{
977977
CX("%b",pContent);
978978
break;
979979
}
980980
case FE_RENDER_WIKI:
981
- wiki_render_by_mimetype(pContent, zMime);
981
+ wiki_render_by_mimetype(pContent, zMime, 0);
982982
break;
983983
default:{
984984
const char *zExt = strrchr(zFilename,'.');
985985
const char *zContent = blob_str(pContent);
986986
if(FE_PREVIEW_LINE_NUMBERS & flags){
987987
--- src/fileedit.c
+++ src/fileedit.c
@@ -976,11 +976,11 @@
976 case FE_RENDER_HTML_INLINE:{
977 CX("%b",pContent);
978 break;
979 }
980 case FE_RENDER_WIKI:
981 wiki_render_by_mimetype(pContent, zMime);
982 break;
983 default:{
984 const char *zExt = strrchr(zFilename,'.');
985 const char *zContent = blob_str(pContent);
986 if(FE_PREVIEW_LINE_NUMBERS & flags){
987
--- src/fileedit.c
+++ src/fileedit.c
@@ -976,11 +976,11 @@
976 case FE_RENDER_HTML_INLINE:{
977 CX("%b",pContent);
978 break;
979 }
980 case FE_RENDER_WIKI:
981 wiki_render_by_mimetype(pContent, zMime, 0);
982 break;
983 default:{
984 const char *zExt = strrchr(zFilename,'.');
985 const char *zContent = blob_str(pContent);
986 if(FE_PREVIEW_LINE_NUMBERS & flags){
987
+1 -2
--- src/forum.c
+++ src/forum.c
@@ -340,12 +340,11 @@
340340
}else{
341341
@ <div class='forumPostFullBody'>
342342
}
343343
blob_init(&x, 0, 0);
344344
blob_append(&x, zContent, -1);
345
- safe_html_enable(1);
346
- wiki_render_by_mimetype(&x, zMimetype);
345
+ wiki_render_by_mimetype(&x, zMimetype, WIKI_SAFE);
347346
blob_reset(&x);
348347
@ </div>
349348
}else{
350349
@ <i>Deleted</i>
351350
}
352351
--- src/forum.c
+++ src/forum.c
@@ -340,12 +340,11 @@
340 }else{
341 @ <div class='forumPostFullBody'>
342 }
343 blob_init(&x, 0, 0);
344 blob_append(&x, zContent, -1);
345 safe_html_enable(1);
346 wiki_render_by_mimetype(&x, zMimetype);
347 blob_reset(&x);
348 @ </div>
349 }else{
350 @ <i>Deleted</i>
351 }
352
--- src/forum.c
+++ src/forum.c
@@ -340,12 +340,11 @@
340 }else{
341 @ <div class='forumPostFullBody'>
342 }
343 blob_init(&x, 0, 0);
344 blob_append(&x, zContent, -1);
345 wiki_render_by_mimetype(&x, zMimetype, WIKI_SAFE);
 
346 blob_reset(&x);
347 @ </div>
348 }else{
349 @ <i>Deleted</i>
350 }
351
+2 -2
--- src/info.c
+++ src/info.c
@@ -1043,11 +1043,11 @@
10431043
}
10441044
10451045
10461046
@ <div class="section">Content</div>
10471047
blob_init(&wiki, pWiki->zWiki, -1);
1048
- wiki_render_by_mimetype(&wiki, pWiki->zMimetype);
1048
+ wiki_render_by_mimetype(&wiki, pWiki->zMimetype, 0);
10491049
blob_reset(&wiki);
10501050
manifest_destroy(pWiki);
10511051
style_footer();
10521052
}
10531053
@@ -2362,11 +2362,11 @@
23622362
style_submenu_element("Content", "%R/artifact/%s", zUuid);
23632363
}else{
23642364
@ <hr />
23652365
content_get(rid, &content);
23662366
if( renderAsWiki ){
2367
- wiki_render_by_mimetype(&content, zMime);
2367
+ wiki_render_by_mimetype(&content, zMime, 0);
23682368
}else if( renderAsHtml ){
23692369
@ <iframe src="%R/raw/%s(zUuid)"
23702370
@ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
23712371
@ sandbox="allow-same-origin" id="ifm1">
23722372
@ </iframe>
23732373
--- src/info.c
+++ src/info.c
@@ -1043,11 +1043,11 @@
1043 }
1044
1045
1046 @ <div class="section">Content</div>
1047 blob_init(&wiki, pWiki->zWiki, -1);
1048 wiki_render_by_mimetype(&wiki, pWiki->zMimetype);
1049 blob_reset(&wiki);
1050 manifest_destroy(pWiki);
1051 style_footer();
1052 }
1053
@@ -2362,11 +2362,11 @@
2362 style_submenu_element("Content", "%R/artifact/%s", zUuid);
2363 }else{
2364 @ <hr />
2365 content_get(rid, &content);
2366 if( renderAsWiki ){
2367 wiki_render_by_mimetype(&content, zMime);
2368 }else if( renderAsHtml ){
2369 @ <iframe src="%R/raw/%s(zUuid)"
2370 @ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
2371 @ sandbox="allow-same-origin" id="ifm1">
2372 @ </iframe>
2373
--- src/info.c
+++ src/info.c
@@ -1043,11 +1043,11 @@
1043 }
1044
1045
1046 @ <div class="section">Content</div>
1047 blob_init(&wiki, pWiki->zWiki, -1);
1048 wiki_render_by_mimetype(&wiki, pWiki->zMimetype, 0);
1049 blob_reset(&wiki);
1050 manifest_destroy(pWiki);
1051 style_footer();
1052 }
1053
@@ -2362,11 +2362,11 @@
2362 style_submenu_element("Content", "%R/artifact/%s", zUuid);
2363 }else{
2364 @ <hr />
2365 content_get(rid, &content);
2366 if( renderAsWiki ){
2367 wiki_render_by_mimetype(&content, zMime, 0);
2368 }else if( renderAsHtml ){
2369 @ <iframe src="%R/raw/%s(zUuid)"
2370 @ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
2371 @ sandbox="allow-same-origin" id="ifm1">
2372 @ </iframe>
2373
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -45,11 +45,11 @@
4545
* the error is not overly explicit.
4646
*/
4747
4848
/* BLOB_APPEND_BLOB -- append blob contents to another */
4949
#define BLOB_APPEND_BLOB(dest, src) \
50
- safe_html_append((dest), blob_buffer(src), blob_size(src))
50
+ blob_append((dest), blob_buffer(src), blob_size(src))
5151
5252
5353
/* HTML escapes
5454
**
5555
** html_escape() converts < to &lt;, > to &gt;, and & to &amp;.
@@ -147,11 +147,11 @@
147147
int nTag = html_tag_length(data);
148148
blob_append(title, data+nTag, size - nTag - 5);
149149
return;
150150
}
151151
INTER_BLOCK(ob);
152
- safe_html_append(ob, data, size);
152
+ blob_append(ob, data, size);
153153
BLOB_APPEND_LITERAL(ob, "\n");
154154
}
155155
156156
static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
157157
INTER_BLOCK(ob);
@@ -215,11 +215,11 @@
215215
){
216216
char *text_data = blob_buffer(text);
217217
size_t text_size = blob_size(text);
218218
while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
219219
BLOB_APPEND_LITERAL(ob, "<li>");
220
- safe_html_append(ob, text_data, text_size);
220
+ blob_append(ob, text_data, text_size);
221221
BLOB_APPEND_LITERAL(ob, "</li>\n");
222222
}
223223
224224
static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
225225
INTER_BLOCK(ob);
226226
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -45,11 +45,11 @@
45 * the error is not overly explicit.
46 */
47
48 /* BLOB_APPEND_BLOB -- append blob contents to another */
49 #define BLOB_APPEND_BLOB(dest, src) \
50 safe_html_append((dest), blob_buffer(src), blob_size(src))
51
52
53 /* HTML escapes
54 **
55 ** html_escape() converts < to &lt;, > to &gt;, and & to &amp;.
@@ -147,11 +147,11 @@
147 int nTag = html_tag_length(data);
148 blob_append(title, data+nTag, size - nTag - 5);
149 return;
150 }
151 INTER_BLOCK(ob);
152 safe_html_append(ob, data, size);
153 BLOB_APPEND_LITERAL(ob, "\n");
154 }
155
156 static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
157 INTER_BLOCK(ob);
@@ -215,11 +215,11 @@
215 ){
216 char *text_data = blob_buffer(text);
217 size_t text_size = blob_size(text);
218 while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
219 BLOB_APPEND_LITERAL(ob, "<li>");
220 safe_html_append(ob, text_data, text_size);
221 BLOB_APPEND_LITERAL(ob, "</li>\n");
222 }
223
224 static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
225 INTER_BLOCK(ob);
226
--- src/markdown_html.c
+++ src/markdown_html.c
@@ -45,11 +45,11 @@
45 * the error is not overly explicit.
46 */
47
48 /* BLOB_APPEND_BLOB -- append blob contents to another */
49 #define BLOB_APPEND_BLOB(dest, src) \
50 blob_append((dest), blob_buffer(src), blob_size(src))
51
52
53 /* HTML escapes
54 **
55 ** html_escape() converts < to &lt;, > to &gt;, and & to &amp;.
@@ -147,11 +147,11 @@
147 int nTag = html_tag_length(data);
148 blob_append(title, data+nTag, size - nTag - 5);
149 return;
150 }
151 INTER_BLOCK(ob);
152 blob_append(ob, data, size);
153 BLOB_APPEND_LITERAL(ob, "\n");
154 }
155
156 static void html_blockcode(struct Blob *ob, struct Blob *text, void *opaque){
157 INTER_BLOCK(ob);
@@ -215,11 +215,11 @@
215 ){
216 char *text_data = blob_buffer(text);
217 size_t text_size = blob_size(text);
218 while( text_size>0 && text_data[text_size-1]=='\n' ) text_size--;
219 BLOB_APPEND_LITERAL(ob, "<li>");
220 blob_append(ob, text_data, text_size);
221 BLOB_APPEND_LITERAL(ob, "</li>\n");
222 }
223
224 static void html_paragraph(struct Blob *ob, struct Blob *text, void *opaque){
225 INTER_BLOCK(ob);
226
+10 -7
--- src/wiki.c
+++ src/wiki.c
@@ -188,17 +188,20 @@
188188
** Render wiki text according to its mimetype.
189189
**
190190
** text/x-fossil-wiki Fossil wiki
191191
** text/x-markdown Markdown
192192
** anything else... Plain text
193
+**
194
+** If zMimetype is a null pointer, then use "text/x-fossil-wiki".
193195
*/
194
-void wiki_render_by_mimetype(Blob *pWiki, const char *zMimetype){
196
+void wiki_render_by_mimetype(Blob *pWiki, const char *zMimetype, int flags){
195197
if( zMimetype==0 || fossil_strcmp(zMimetype, "text/x-fossil-wiki")==0 ){
196
- wiki_convert(pWiki, 0, 0);
198
+ wiki_convert(pWiki, 0, flags);
197199
}else if( fossil_strcmp(zMimetype, "text/x-markdown")==0 ){
198200
Blob tail = BLOB_INITIALIZER;
199201
markdown_to_html(pWiki, 0, &tail);
202
+ if( flags & WIKI_SAFE ) safe_html(&tail);
200203
@ %s(blob_str(&tail))
201204
blob_reset(&tail);
202205
}else{
203206
@ <pre class='textPlain'>
204207
@ %h(blob_str(pWiki))
@@ -220,11 +223,11 @@
220223
}else{
221224
style_submenu_element("Plain-Text", "%R/md_rules?txt=1");
222225
}
223226
blob_init(&x, builtin_text("markdown.md"), -1);
224227
blob_materialize(&x);
225
- wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown");
228
+ wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown", 0);
226229
blob_reset(&x);
227230
style_footer();
228231
}
229232
230233
/*
@@ -241,11 +244,11 @@
241244
}else{
242245
style_submenu_element("Plain-Text", "%R/wiki_rules?txt=1");
243246
}
244247
blob_init(&x, builtin_text("wiki.wiki"), -1);
245248
blob_materialize(&x);
246
- wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-fossil-wiki");
249
+ wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-fossil-wiki", 0);
247250
blob_reset(&x);
248251
style_footer();
249252
}
250253
251254
/*
@@ -558,11 +561,11 @@
558561
}
559562
if( zBody[0]==0 ){
560563
@ <i>This page has been deleted</i>
561564
}else{
562565
blob_init(&wiki, zBody, -1);
563
- wiki_render_by_mimetype(&wiki, zMimetype);
566
+ wiki_render_by_mimetype(&wiki, zMimetype, WIKI_SAFE);
564567
blob_reset(&wiki);
565568
}
566569
attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
567570
manifest_destroy(pWiki);
568571
style_footer();
@@ -745,11 +748,11 @@
745748
blob_append(&wiki, zBody, -1);
746749
if( P("preview")!=0 ){
747750
havePreview = 1;
748751
if( zBody[0] ){
749752
@ Preview:<hr />
750
- wiki_render_by_mimetype(&wiki, zMimetype);
753
+ wiki_render_by_mimetype(&wiki, zMimetype, WIKI_SAFE);
751754
@ <hr />
752755
blob_reset(&wiki);
753756
}
754757
}
755758
for(n=2, z=zBody; z[0]; z++){
@@ -1007,11 +1010,11 @@
10071010
if( P("preview")!=0 ){
10081011
Blob preview;
10091012
blob_zero(&preview);
10101013
appendRemark(&preview, zMimetype);
10111014
@ Preview:<hr />
1012
- wiki_render_by_mimetype(&preview, zMimetype);
1015
+ wiki_render_by_mimetype(&preview, zMimetype, WIKI_SAFE);
10131016
@ <hr />
10141017
blob_reset(&preview);
10151018
}
10161019
zUser = PD("u", g.zLogin);
10171020
form_begin(0, "%R/wikiappend");
10181021
--- src/wiki.c
+++ src/wiki.c
@@ -188,17 +188,20 @@
188 ** Render wiki text according to its mimetype.
189 **
190 ** text/x-fossil-wiki Fossil wiki
191 ** text/x-markdown Markdown
192 ** anything else... Plain text
 
 
193 */
194 void wiki_render_by_mimetype(Blob *pWiki, const char *zMimetype){
195 if( zMimetype==0 || fossil_strcmp(zMimetype, "text/x-fossil-wiki")==0 ){
196 wiki_convert(pWiki, 0, 0);
197 }else if( fossil_strcmp(zMimetype, "text/x-markdown")==0 ){
198 Blob tail = BLOB_INITIALIZER;
199 markdown_to_html(pWiki, 0, &tail);
 
200 @ %s(blob_str(&tail))
201 blob_reset(&tail);
202 }else{
203 @ <pre class='textPlain'>
204 @ %h(blob_str(pWiki))
@@ -220,11 +223,11 @@
220 }else{
221 style_submenu_element("Plain-Text", "%R/md_rules?txt=1");
222 }
223 blob_init(&x, builtin_text("markdown.md"), -1);
224 blob_materialize(&x);
225 wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown");
226 blob_reset(&x);
227 style_footer();
228 }
229
230 /*
@@ -241,11 +244,11 @@
241 }else{
242 style_submenu_element("Plain-Text", "%R/wiki_rules?txt=1");
243 }
244 blob_init(&x, builtin_text("wiki.wiki"), -1);
245 blob_materialize(&x);
246 wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-fossil-wiki");
247 blob_reset(&x);
248 style_footer();
249 }
250
251 /*
@@ -558,11 +561,11 @@
558 }
559 if( zBody[0]==0 ){
560 @ <i>This page has been deleted</i>
561 }else{
562 blob_init(&wiki, zBody, -1);
563 wiki_render_by_mimetype(&wiki, zMimetype);
564 blob_reset(&wiki);
565 }
566 attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
567 manifest_destroy(pWiki);
568 style_footer();
@@ -745,11 +748,11 @@
745 blob_append(&wiki, zBody, -1);
746 if( P("preview")!=0 ){
747 havePreview = 1;
748 if( zBody[0] ){
749 @ Preview:<hr />
750 wiki_render_by_mimetype(&wiki, zMimetype);
751 @ <hr />
752 blob_reset(&wiki);
753 }
754 }
755 for(n=2, z=zBody; z[0]; z++){
@@ -1007,11 +1010,11 @@
1007 if( P("preview")!=0 ){
1008 Blob preview;
1009 blob_zero(&preview);
1010 appendRemark(&preview, zMimetype);
1011 @ Preview:<hr />
1012 wiki_render_by_mimetype(&preview, zMimetype);
1013 @ <hr />
1014 blob_reset(&preview);
1015 }
1016 zUser = PD("u", g.zLogin);
1017 form_begin(0, "%R/wikiappend");
1018
--- src/wiki.c
+++ src/wiki.c
@@ -188,17 +188,20 @@
188 ** Render wiki text according to its mimetype.
189 **
190 ** text/x-fossil-wiki Fossil wiki
191 ** text/x-markdown Markdown
192 ** anything else... Plain text
193 **
194 ** If zMimetype is a null pointer, then use "text/x-fossil-wiki".
195 */
196 void wiki_render_by_mimetype(Blob *pWiki, const char *zMimetype, int flags){
197 if( zMimetype==0 || fossil_strcmp(zMimetype, "text/x-fossil-wiki")==0 ){
198 wiki_convert(pWiki, 0, flags);
199 }else if( fossil_strcmp(zMimetype, "text/x-markdown")==0 ){
200 Blob tail = BLOB_INITIALIZER;
201 markdown_to_html(pWiki, 0, &tail);
202 if( flags & WIKI_SAFE ) safe_html(&tail);
203 @ %s(blob_str(&tail))
204 blob_reset(&tail);
205 }else{
206 @ <pre class='textPlain'>
207 @ %h(blob_str(pWiki))
@@ -220,11 +223,11 @@
223 }else{
224 style_submenu_element("Plain-Text", "%R/md_rules?txt=1");
225 }
226 blob_init(&x, builtin_text("markdown.md"), -1);
227 blob_materialize(&x);
228 wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown", 0);
229 blob_reset(&x);
230 style_footer();
231 }
232
233 /*
@@ -241,11 +244,11 @@
244 }else{
245 style_submenu_element("Plain-Text", "%R/wiki_rules?txt=1");
246 }
247 blob_init(&x, builtin_text("wiki.wiki"), -1);
248 blob_materialize(&x);
249 wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-fossil-wiki", 0);
250 blob_reset(&x);
251 style_footer();
252 }
253
254 /*
@@ -558,11 +561,11 @@
561 }
562 if( zBody[0]==0 ){
563 @ <i>This page has been deleted</i>
564 }else{
565 blob_init(&wiki, zBody, -1);
566 wiki_render_by_mimetype(&wiki, zMimetype, WIKI_SAFE);
567 blob_reset(&wiki);
568 }
569 attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
570 manifest_destroy(pWiki);
571 style_footer();
@@ -745,11 +748,11 @@
748 blob_append(&wiki, zBody, -1);
749 if( P("preview")!=0 ){
750 havePreview = 1;
751 if( zBody[0] ){
752 @ Preview:<hr />
753 wiki_render_by_mimetype(&wiki, zMimetype, WIKI_SAFE);
754 @ <hr />
755 blob_reset(&wiki);
756 }
757 }
758 for(n=2, z=zBody; z[0]; z++){
@@ -1007,11 +1010,11 @@
1010 if( P("preview")!=0 ){
1011 Blob preview;
1012 blob_zero(&preview);
1013 appendRemark(&preview, zMimetype);
1014 @ Preview:<hr />
1015 wiki_render_by_mimetype(&preview, zMimetype, WIKI_SAFE);
1016 @ <hr />
1017 blob_reset(&preview);
1018 }
1019 zUser = PD("u", g.zLogin);
1020 form_begin(0, "%R/wikiappend");
1021
+42 -27
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -31,10 +31,11 @@
3131
#define WIKI_BUTTONS 0x008 /* Allow sub-menu buttons */
3232
#define WIKI_NOBADLINKS 0x010 /* Ignore broken hyperlinks */
3333
#define WIKI_LINKSONLY 0x020 /* No markup. Only decorate links */
3434
#define WIKI_NEWLINE 0x040 /* Honor \n - break lines at each \n */
3535
#define WIKI_MARKDOWNLINKS 0x080 /* Resolve hyperlinks as in markdown */
36
+#define WIKI_SAFE 0x100 /* Make the result safe for embedding */
3637
#endif
3738
3839
3940
/*
4041
** These are the only markup attributes allowed.
@@ -1744,13 +1745,10 @@
17441745
Renderer renderer;
17451746
17461747
memset(&renderer, 0, sizeof(renderer));
17471748
renderer.renderFlags = flags;
17481749
renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH|flags;
1749
- if( flags & WIKI_NOBLOCK ){
1750
- renderer.state |= INLINE_MARKUP_ONLY;
1751
- }
17521750
if( flags & WIKI_INLINE ){
17531751
renderer.wantAutoParagraph = 0;
17541752
}else{
17551753
renderer.wantAutoParagraph = 1;
17561754
}
@@ -1818,22 +1816,22 @@
18181816
** --safe Do "safe-html" rendering.
18191817
*/
18201818
void test_markdown_render(void){
18211819
Blob in, out;
18221820
int i;
1821
+ int bSafe = 0;
18231822
db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
1824
- if( find_option("safe",0,0)!=0 ){
1825
- safe_html_enable(1);
1826
- }
1823
+ bSafe = find_option("safe",0,0)!=0;
18271824
verify_all_options();
18281825
for(i=2; i<g.argc; i++){
18291826
blob_zero(&out);
18301827
blob_read_from_file(&in, g.argv[i], ExtFILE);
18311828
if( g.argc>3 ){
18321829
fossil_print("<!------ %h ------->\n", g.argv[i]);
18331830
}
18341831
markdown_to_html(&in, 0, &out);
1832
+ if( bSafe ) safe_html(&out);
18351833
blob_write_to_file(&out, "-");
18361834
blob_reset(&in);
18371835
blob_reset(&out);
18381836
}
18391837
}
@@ -2509,20 +2507,10 @@
25092507
blob_appendf(pBlob, "</%s>", aMarkup[e].zName);
25102508
}
25112509
}while( e!=eEnd && p->n>0 );
25122510
}
25132511
2514
-/*
2515
-** Enable or disable the "safe-html" feature. When enabled, the
2516
-** HTML generated by Markdown is adjusted so that it cannot cause
2517
-** problems when embedded in a larger document.
2518
-*/
2519
-static int safeHtml = 0;
2520
-void safe_html_enable(int v){
2521
- safeHtml = v;
2522
-}
2523
-
25242512
/*
25252513
** Append HTML text to a Blob object.
25262514
**
25272515
** If safe-html is enabled then the appended text is modified
25282516
** changed in the following ways:
@@ -2553,14 +2541,10 @@
25532541
int i, j, n;
25542542
HtmlTagStack s;
25552543
ParsedMarkup markup;
25562544
25572545
if( nHtml<=0 ) return;
2558
- if( !safeHtml ){
2559
- blob_append(pBlob, zHtml, nHtml);
2560
- return;
2561
- }
25622546
cLast = zHtml[nHtml];
25632547
zHtml[nHtml] = 0;
25642548
html_tagstack_init(&s);
25652549
25662550
i = 0;
@@ -2586,10 +2570,12 @@
25862570
}
25872571
parseMarkup(&markup, zHtml+j);
25882572
if( markup.iCode==MARKUP_INVALID ){
25892573
blob_appendf(pBlob, "<span class='error'>&lt;%.*s&gt;</span>",
25902574
n-2, zHtml+j+1);
2575
+ }else if( (markup.iType & MUTYPE_Nested)==0 || markup.iCode==MARKUP_P ){
2576
+ renderMarkup(pBlob, &markup);
25912577
}else{
25922578
if( markup.endTag ){
25932579
html_tagstack_pop(&s, pBlob, markup.iCode);
25942580
}else{
25952581
renderMarkup(pBlob, &markup);
@@ -2601,10 +2587,42 @@
26012587
html_tagstack_pop(&s, pBlob, 0);
26022588
html_tagstack_clear(&s);
26032589
zHtml[nHtml] = cLast;
26042590
}
26052591
2592
+/*
2593
+** The input blob consists of HTML. Convert it into "safe HTML". Safe
2594
+** HTML has no potentially disruptive elements (ex: <script>, <style>)
2595
+** and it is embeddable, meaning that it won't close any outer elements
2596
+** from the script in which it is embedded, nor will it leave any open
2597
+** elements to affect the tail of the outer script.
2598
+*/
2599
+void safe_html(Blob *in){
2600
+ Blob out;
2601
+ char *z = blob_str(in);
2602
+ int n = blob_size(in);
2603
+ int k;
2604
+ blob_init(&out, 0, 0);
2605
+ while( fossil_isspace(z[0]) ){ z++; n--; }
2606
+ for(k=n-1; k>5 && fossil_isspace(z[k]); k--){}
2607
+
2608
+ if( fossil_strnicmp(z, "<div",4)==0 && !fossil_isalpha(z[4])
2609
+ && fossil_strnicmp(z+k-5, "</div>",6)==0
2610
+ ){
2611
+ /* The input contains an outer <div>...</div>. Preserve the
2612
+ ** full scope of that <div>. */
2613
+ int m = html_tag_length(z);
2614
+ k -= 5;
2615
+ blob_append(&out, z, m);
2616
+ safe_html_append(&out, z+m, k-m);
2617
+ blob_append(&out, z+k, n-k);
2618
+ }else{
2619
+ safe_html_append(&out, z, n);
2620
+ }
2621
+ blob_reset(in);
2622
+ *in = out;
2623
+}
26062624
26072625
/*
26082626
** COMMAND: test-safe-html
26092627
**
26102628
** Usage: %fossil test-safe-html FILE ...
@@ -2614,21 +2632,18 @@
26142632
** standard output.
26152633
*/
26162634
void test_safe_html_cmd(void){
26172635
int i;
26182636
Blob x;
2619
- Blob y;
26202637
for(i=2; i<g.argc; i++){
26212638
char *z;
26222639
int n;
26232640
blob_read_from_file(&x, g.argv[i], ExtFILE);
2624
- blob_init(&y, 0, 0);
26252641
blob_terminate(&x);
2626
- safe_html_append(&y, blob_buffer(&x), blob_size(&x));
2627
- blob_reset(&x);
2628
- z = blob_str(&y);
2629
- n = blob_size(&y);
2642
+ safe_html(&x);
2643
+ z = blob_str(&x);
2644
+ n = blob_size(&x);
26302645
while( n>0 && (z[n-1]=='\n' || z[n-1]=='\r') ) n--;
26312646
fossil_print("%.*s\n", n, z);
2632
- blob_reset(&y);
2647
+ blob_reset(&x);
26332648
}
26342649
}
26352650
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -31,10 +31,11 @@
31 #define WIKI_BUTTONS 0x008 /* Allow sub-menu buttons */
32 #define WIKI_NOBADLINKS 0x010 /* Ignore broken hyperlinks */
33 #define WIKI_LINKSONLY 0x020 /* No markup. Only decorate links */
34 #define WIKI_NEWLINE 0x040 /* Honor \n - break lines at each \n */
35 #define WIKI_MARKDOWNLINKS 0x080 /* Resolve hyperlinks as in markdown */
 
36 #endif
37
38
39 /*
40 ** These are the only markup attributes allowed.
@@ -1744,13 +1745,10 @@
1744 Renderer renderer;
1745
1746 memset(&renderer, 0, sizeof(renderer));
1747 renderer.renderFlags = flags;
1748 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH|flags;
1749 if( flags & WIKI_NOBLOCK ){
1750 renderer.state |= INLINE_MARKUP_ONLY;
1751 }
1752 if( flags & WIKI_INLINE ){
1753 renderer.wantAutoParagraph = 0;
1754 }else{
1755 renderer.wantAutoParagraph = 1;
1756 }
@@ -1818,22 +1816,22 @@
1818 ** --safe Do "safe-html" rendering.
1819 */
1820 void test_markdown_render(void){
1821 Blob in, out;
1822 int i;
 
1823 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
1824 if( find_option("safe",0,0)!=0 ){
1825 safe_html_enable(1);
1826 }
1827 verify_all_options();
1828 for(i=2; i<g.argc; i++){
1829 blob_zero(&out);
1830 blob_read_from_file(&in, g.argv[i], ExtFILE);
1831 if( g.argc>3 ){
1832 fossil_print("<!------ %h ------->\n", g.argv[i]);
1833 }
1834 markdown_to_html(&in, 0, &out);
 
1835 blob_write_to_file(&out, "-");
1836 blob_reset(&in);
1837 blob_reset(&out);
1838 }
1839 }
@@ -2509,20 +2507,10 @@
2509 blob_appendf(pBlob, "</%s>", aMarkup[e].zName);
2510 }
2511 }while( e!=eEnd && p->n>0 );
2512 }
2513
2514 /*
2515 ** Enable or disable the "safe-html" feature. When enabled, the
2516 ** HTML generated by Markdown is adjusted so that it cannot cause
2517 ** problems when embedded in a larger document.
2518 */
2519 static int safeHtml = 0;
2520 void safe_html_enable(int v){
2521 safeHtml = v;
2522 }
2523
2524 /*
2525 ** Append HTML text to a Blob object.
2526 **
2527 ** If safe-html is enabled then the appended text is modified
2528 ** changed in the following ways:
@@ -2553,14 +2541,10 @@
2553 int i, j, n;
2554 HtmlTagStack s;
2555 ParsedMarkup markup;
2556
2557 if( nHtml<=0 ) return;
2558 if( !safeHtml ){
2559 blob_append(pBlob, zHtml, nHtml);
2560 return;
2561 }
2562 cLast = zHtml[nHtml];
2563 zHtml[nHtml] = 0;
2564 html_tagstack_init(&s);
2565
2566 i = 0;
@@ -2586,10 +2570,12 @@
2586 }
2587 parseMarkup(&markup, zHtml+j);
2588 if( markup.iCode==MARKUP_INVALID ){
2589 blob_appendf(pBlob, "<span class='error'>&lt;%.*s&gt;</span>",
2590 n-2, zHtml+j+1);
 
 
2591 }else{
2592 if( markup.endTag ){
2593 html_tagstack_pop(&s, pBlob, markup.iCode);
2594 }else{
2595 renderMarkup(pBlob, &markup);
@@ -2601,10 +2587,42 @@
2601 html_tagstack_pop(&s, pBlob, 0);
2602 html_tagstack_clear(&s);
2603 zHtml[nHtml] = cLast;
2604 }
2605
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2606
2607 /*
2608 ** COMMAND: test-safe-html
2609 **
2610 ** Usage: %fossil test-safe-html FILE ...
@@ -2614,21 +2632,18 @@
2614 ** standard output.
2615 */
2616 void test_safe_html_cmd(void){
2617 int i;
2618 Blob x;
2619 Blob y;
2620 for(i=2; i<g.argc; i++){
2621 char *z;
2622 int n;
2623 blob_read_from_file(&x, g.argv[i], ExtFILE);
2624 blob_init(&y, 0, 0);
2625 blob_terminate(&x);
2626 safe_html_append(&y, blob_buffer(&x), blob_size(&x));
2627 blob_reset(&x);
2628 z = blob_str(&y);
2629 n = blob_size(&y);
2630 while( n>0 && (z[n-1]=='\n' || z[n-1]=='\r') ) n--;
2631 fossil_print("%.*s\n", n, z);
2632 blob_reset(&y);
2633 }
2634 }
2635
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -31,10 +31,11 @@
31 #define WIKI_BUTTONS 0x008 /* Allow sub-menu buttons */
32 #define WIKI_NOBADLINKS 0x010 /* Ignore broken hyperlinks */
33 #define WIKI_LINKSONLY 0x020 /* No markup. Only decorate links */
34 #define WIKI_NEWLINE 0x040 /* Honor \n - break lines at each \n */
35 #define WIKI_MARKDOWNLINKS 0x080 /* Resolve hyperlinks as in markdown */
36 #define WIKI_SAFE 0x100 /* Make the result safe for embedding */
37 #endif
38
39
40 /*
41 ** These are the only markup attributes allowed.
@@ -1744,13 +1745,10 @@
1745 Renderer renderer;
1746
1747 memset(&renderer, 0, sizeof(renderer));
1748 renderer.renderFlags = flags;
1749 renderer.state = ALLOW_WIKI|AT_NEWLINE|AT_PARAGRAPH|flags;
 
 
 
1750 if( flags & WIKI_INLINE ){
1751 renderer.wantAutoParagraph = 0;
1752 }else{
1753 renderer.wantAutoParagraph = 1;
1754 }
@@ -1818,22 +1816,22 @@
1816 ** --safe Do "safe-html" rendering.
1817 */
1818 void test_markdown_render(void){
1819 Blob in, out;
1820 int i;
1821 int bSafe = 0;
1822 db_find_and_open_repository(OPEN_OK_NOT_FOUND|OPEN_SUBSTITUTE,0);
1823 bSafe = find_option("safe",0,0)!=0;
 
 
1824 verify_all_options();
1825 for(i=2; i<g.argc; i++){
1826 blob_zero(&out);
1827 blob_read_from_file(&in, g.argv[i], ExtFILE);
1828 if( g.argc>3 ){
1829 fossil_print("<!------ %h ------->\n", g.argv[i]);
1830 }
1831 markdown_to_html(&in, 0, &out);
1832 if( bSafe ) safe_html(&out);
1833 blob_write_to_file(&out, "-");
1834 blob_reset(&in);
1835 blob_reset(&out);
1836 }
1837 }
@@ -2509,20 +2507,10 @@
2507 blob_appendf(pBlob, "</%s>", aMarkup[e].zName);
2508 }
2509 }while( e!=eEnd && p->n>0 );
2510 }
2511
 
 
 
 
 
 
 
 
 
 
2512 /*
2513 ** Append HTML text to a Blob object.
2514 **
2515 ** If safe-html is enabled then the appended text is modified
2516 ** changed in the following ways:
@@ -2553,14 +2541,10 @@
2541 int i, j, n;
2542 HtmlTagStack s;
2543 ParsedMarkup markup;
2544
2545 if( nHtml<=0 ) return;
 
 
 
 
2546 cLast = zHtml[nHtml];
2547 zHtml[nHtml] = 0;
2548 html_tagstack_init(&s);
2549
2550 i = 0;
@@ -2586,10 +2570,12 @@
2570 }
2571 parseMarkup(&markup, zHtml+j);
2572 if( markup.iCode==MARKUP_INVALID ){
2573 blob_appendf(pBlob, "<span class='error'>&lt;%.*s&gt;</span>",
2574 n-2, zHtml+j+1);
2575 }else if( (markup.iType & MUTYPE_Nested)==0 || markup.iCode==MARKUP_P ){
2576 renderMarkup(pBlob, &markup);
2577 }else{
2578 if( markup.endTag ){
2579 html_tagstack_pop(&s, pBlob, markup.iCode);
2580 }else{
2581 renderMarkup(pBlob, &markup);
@@ -2601,10 +2587,42 @@
2587 html_tagstack_pop(&s, pBlob, 0);
2588 html_tagstack_clear(&s);
2589 zHtml[nHtml] = cLast;
2590 }
2591
2592 /*
2593 ** The input blob consists of HTML. Convert it into "safe HTML". Safe
2594 ** HTML has no potentially disruptive elements (ex: <script>, <style>)
2595 ** and it is embeddable, meaning that it won't close any outer elements
2596 ** from the script in which it is embedded, nor will it leave any open
2597 ** elements to affect the tail of the outer script.
2598 */
2599 void safe_html(Blob *in){
2600 Blob out;
2601 char *z = blob_str(in);
2602 int n = blob_size(in);
2603 int k;
2604 blob_init(&out, 0, 0);
2605 while( fossil_isspace(z[0]) ){ z++; n--; }
2606 for(k=n-1; k>5 && fossil_isspace(z[k]); k--){}
2607
2608 if( fossil_strnicmp(z, "<div",4)==0 && !fossil_isalpha(z[4])
2609 && fossil_strnicmp(z+k-5, "</div>",6)==0
2610 ){
2611 /* The input contains an outer <div>...</div>. Preserve the
2612 ** full scope of that <div>. */
2613 int m = html_tag_length(z);
2614 k -= 5;
2615 blob_append(&out, z, m);
2616 safe_html_append(&out, z+m, k-m);
2617 blob_append(&out, z+k, n-k);
2618 }else{
2619 safe_html_append(&out, z, n);
2620 }
2621 blob_reset(in);
2622 *in = out;
2623 }
2624
2625 /*
2626 ** COMMAND: test-safe-html
2627 **
2628 ** Usage: %fossil test-safe-html FILE ...
@@ -2614,21 +2632,18 @@
2632 ** standard output.
2633 */
2634 void test_safe_html_cmd(void){
2635 int i;
2636 Blob x;
 
2637 for(i=2; i<g.argc; i++){
2638 char *z;
2639 int n;
2640 blob_read_from_file(&x, g.argv[i], ExtFILE);
 
2641 blob_terminate(&x);
2642 safe_html(&x);
2643 z = blob_str(&x);
2644 n = blob_size(&x);
 
2645 while( n>0 && (z[n-1]=='\n' || z[n-1]=='\r') ) n--;
2646 fossil_print("%.*s\n", n, z);
2647 blob_reset(&x);
2648 }
2649 }
2650

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button