Fossil SCM

Add the safe-html setting that determines which kinds of documents are allowed to generate unsafe HTML from Markdown.

drh 2020-06-02 20:05 trunk
Commit 89b6dda99c45533358f1af425acc226fec851c8f325565d24980bb2f1fe1aa02
+2 -1
--- src/browse.c
+++ src/browse.c
@@ -390,11 +390,12 @@
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, 0);
395
+ safe_html_context(DOCSRC_FILE);
396
+ wiki_render_by_mimetype(&content, zMime);
396397
}
397398
}
398399
}
399400
db_finalize(&q);
400401
style_footer();
401402
--- src/browse.c
+++ src/browse.c
@@ -390,11 +390,12 @@
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
--- src/browse.c
+++ src/browse.c
@@ -390,11 +390,12 @@
390 @ </iframe>
391 }else{
392 Blob content;
393 const char *zMime = mimetype_from_name(zName);
394 content_get(rid, &content);
395 safe_html_context(DOCSRC_FILE);
396 wiki_render_by_mimetype(&content, zMime);
397 }
398 }
399 }
400 db_finalize(&q);
401 style_footer();
402
+2 -1
--- src/event.c
+++ src/event.c
@@ -508,11 +508,12 @@
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, 0);
513
+ safe_html_context(DOCSRC_WIKI);
514
+ wiki_render_by_mimetype(&event, zMimetype);
514515
@ </blockquote><hr />
515516
blob_reset(&event);
516517
}
517518
for(n=2, z=zBody; z[0]; z++){
518519
if( z[0]=='\n' ) n++;
519520
--- src/event.c
+++ src/event.c
@@ -508,11 +508,12 @@
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
--- src/event.c
+++ src/event.c
@@ -508,11 +508,12 @@
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 safe_html_context(DOCSRC_WIKI);
514 wiki_render_by_mimetype(&event, zMimetype);
515 @ </blockquote><hr />
516 blob_reset(&event);
517 }
518 for(n=2, z=zBody; z[0]; z++){
519 if( z[0]=='\n' ) n++;
520
+2 -1
--- src/fileedit.c
+++ src/fileedit.c
@@ -976,11 +976,12 @@
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, 0);
981
+ safe_html_context(DOCSRC_FILE);
982
+ wiki_render_by_mimetype(pContent, zMime);
982983
break;
983984
default:{
984985
const char *zExt = strrchr(zFilename,'.');
985986
const char *zContent = blob_str(pContent);
986987
if(FE_PREVIEW_LINE_NUMBERS & flags){
987988
--- src/fileedit.c
+++ src/fileedit.c
@@ -976,11 +976,12 @@
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
--- src/fileedit.c
+++ src/fileedit.c
@@ -976,11 +976,12 @@
976 case FE_RENDER_HTML_INLINE:{
977 CX("%b",pContent);
978 break;
979 }
980 case FE_RENDER_WIKI:
981 safe_html_context(DOCSRC_FILE);
982 wiki_render_by_mimetype(pContent, zMime);
983 break;
984 default:{
985 const char *zExt = strrchr(zFilename,'.');
986 const char *zContent = blob_str(pContent);
987 if(FE_PREVIEW_LINE_NUMBERS & flags){
988
+2 -1
--- src/forum.c
+++ src/forum.c
@@ -340,11 +340,12 @@
340340
}else{
341341
@ <div class='forumPostFullBody'>
342342
}
343343
blob_init(&x, 0, 0);
344344
blob_append(&x, zContent, -1);
345
- wiki_render_by_mimetype(&x, zMimetype, WIKI_SAFE);
345
+ safe_html_context(DOCSRC_FORUM);
346
+ wiki_render_by_mimetype(&x, zMimetype);
346347
blob_reset(&x);
347348
@ </div>
348349
}else{
349350
@ <i>Deleted</i>
350351
}
351352
--- src/forum.c
+++ src/forum.c
@@ -340,11 +340,12 @@
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
--- src/forum.c
+++ src/forum.c
@@ -340,11 +340,12 @@
340 }else{
341 @ <div class='forumPostFullBody'>
342 }
343 blob_init(&x, 0, 0);
344 blob_append(&x, zContent, -1);
345 safe_html_context(DOCSRC_FORUM);
346 wiki_render_by_mimetype(&x, zMimetype);
347 blob_reset(&x);
348 @ </div>
349 }else{
350 @ <i>Deleted</i>
351 }
352
+4 -2
--- src/info.c
+++ src/info.c
@@ -1043,11 +1043,12 @@
10431043
}
10441044
10451045
10461046
@ <div class="section">Content</div>
10471047
blob_init(&wiki, pWiki->zWiki, -1);
1048
- wiki_render_by_mimetype(&wiki, pWiki->zMimetype, 0);
1048
+ safe_html_context(DOCSRC_WIKI);
1049
+ wiki_render_by_mimetype(&wiki, pWiki->zMimetype);
10491050
blob_reset(&wiki);
10501051
manifest_destroy(pWiki);
10511052
style_footer();
10521053
}
10531054
@@ -2362,11 +2363,12 @@
23622363
style_submenu_element("Content", "%R/artifact/%s", zUuid);
23632364
}else{
23642365
@ <hr />
23652366
content_get(rid, &content);
23662367
if( renderAsWiki ){
2367
- wiki_render_by_mimetype(&content, zMime, 0);
2368
+ safe_html_context(DOCSRC_FILE);
2369
+ wiki_render_by_mimetype(&content, zMime);
23682370
}else if( renderAsHtml ){
23692371
@ <iframe src="%R/raw/%s(zUuid)"
23702372
@ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
23712373
@ sandbox="allow-same-origin" id="ifm1">
23722374
@ </iframe>
23732375
--- src/info.c
+++ src/info.c
@@ -1043,11 +1043,12 @@
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 +2363,12 @@
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/info.c
+++ src/info.c
@@ -1043,11 +1043,12 @@
1043 }
1044
1045
1046 @ <div class="section">Content</div>
1047 blob_init(&wiki, pWiki->zWiki, -1);
1048 safe_html_context(DOCSRC_WIKI);
1049 wiki_render_by_mimetype(&wiki, pWiki->zMimetype);
1050 blob_reset(&wiki);
1051 manifest_destroy(pWiki);
1052 style_footer();
1053 }
1054
@@ -2362,11 +2363,12 @@
2363 style_submenu_element("Content", "%R/artifact/%s", zUuid);
2364 }else{
2365 @ <hr />
2366 content_get(rid, &content);
2367 if( renderAsWiki ){
2368 safe_html_context(DOCSRC_FILE);
2369 wiki_render_by_mimetype(&content, zMime);
2370 }else if( renderAsHtml ){
2371 @ <iframe src="%R/raw/%s(zUuid)"
2372 @ width="100%%" frameborder="0" marginwidth="0" marginheight="0"
2373 @ sandbox="allow-same-origin" id="ifm1">
2374 @ </iframe>
2375
+21
--- src/setup.c
+++ src/setup.c
@@ -1052,10 +1052,31 @@
10521052
@ <li> <b>branch/</b><i>branch-name</i>
10531053
@ <li> <b>checkin/</b><i>full-checkin-hash</i>
10541054
@ <li> <b>tag/</b><i>tag-name</i>
10551055
@ </ul>
10561056
@ (Property: "wiki-about")</p>
1057
+ @ <hr />
1058
+ entry_attribute("Allow Unsafe HTML In Markdown", 6,
1059
+ "safe-html", "safe-html", "", 0);
1060
+ @ <p>Allow "unsafe" HTML (ex: &lt;script&gt;, &lt;form&gt;, etc) to be
1061
+ @ generated by <a href="%R/md_rules">Markdown-formatted</a> documents.
1062
+ @ This setting is a string where each character indicates a "type" of
1063
+ @ document in which to allow unsafe HTML:
1064
+ @ <ul>
1065
+ @ <li> <b>b</b> &rarr; checked-in files, embedded documentation
1066
+ @ <li> <b>f</b> &rarr; forum posts
1067
+ @ <li> <b>t</b> &rarr; tickets
1068
+ @ <li> <b>w</b> &rarr; wiki pages
1069
+ @ </ul>
1070
+ @ Include letters for each type of document for which unsafe HTML should
1071
+ @ be allowed. For example, to allow unsafe HTML only for checked-in files,
1072
+ @ make this setting be just "<b>b</b>". To allow unsafe HTML anywhere except
1073
+ @ in forum posts, make this setting be "<b>btw</b>". The default is an
1074
+ @ empty string which means that Fossil never allows Markdown documents
1075
+ @ to generate unsafe HTML.
1076
+ @ (Property: "safe-html")</p>
1077
+ @ <hr />
10571078
@ <hr />
10581079
onoff_attribute("Enable WYSIWYG Wiki Editing",
10591080
"wysiwyg-wiki", "wysiwyg-wiki", 0, 0);
10601081
@ <p>Enable what-you-see-is-what-you-get (WYSIWYG) editing of wiki pages.
10611082
@ The WYSIWYG editor generates HTML instead of markup, which makes
10621083
--- src/setup.c
+++ src/setup.c
@@ -1052,10 +1052,31 @@
1052 @ <li> <b>branch/</b><i>branch-name</i>
1053 @ <li> <b>checkin/</b><i>full-checkin-hash</i>
1054 @ <li> <b>tag/</b><i>tag-name</i>
1055 @ </ul>
1056 @ (Property: "wiki-about")</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1057 @ <hr />
1058 onoff_attribute("Enable WYSIWYG Wiki Editing",
1059 "wysiwyg-wiki", "wysiwyg-wiki", 0, 0);
1060 @ <p>Enable what-you-see-is-what-you-get (WYSIWYG) editing of wiki pages.
1061 @ The WYSIWYG editor generates HTML instead of markup, which makes
1062
--- src/setup.c
+++ src/setup.c
@@ -1052,10 +1052,31 @@
1052 @ <li> <b>branch/</b><i>branch-name</i>
1053 @ <li> <b>checkin/</b><i>full-checkin-hash</i>
1054 @ <li> <b>tag/</b><i>tag-name</i>
1055 @ </ul>
1056 @ (Property: "wiki-about")</p>
1057 @ <hr />
1058 entry_attribute("Allow Unsafe HTML In Markdown", 6,
1059 "safe-html", "safe-html", "", 0);
1060 @ <p>Allow "unsafe" HTML (ex: &lt;script&gt;, &lt;form&gt;, etc) to be
1061 @ generated by <a href="%R/md_rules">Markdown-formatted</a> documents.
1062 @ This setting is a string where each character indicates a "type" of
1063 @ document in which to allow unsafe HTML:
1064 @ <ul>
1065 @ <li> <b>b</b> &rarr; checked-in files, embedded documentation
1066 @ <li> <b>f</b> &rarr; forum posts
1067 @ <li> <b>t</b> &rarr; tickets
1068 @ <li> <b>w</b> &rarr; wiki pages
1069 @ </ul>
1070 @ Include letters for each type of document for which unsafe HTML should
1071 @ be allowed. For example, to allow unsafe HTML only for checked-in files,
1072 @ make this setting be just "<b>b</b>". To allow unsafe HTML anywhere except
1073 @ in forum posts, make this setting be "<b>btw</b>". The default is an
1074 @ empty string which means that Fossil never allows Markdown documents
1075 @ to generate unsafe HTML.
1076 @ (Property: "safe-html")</p>
1077 @ <hr />
1078 @ <hr />
1079 onoff_attribute("Enable WYSIWYG Wiki Editing",
1080 "wysiwyg-wiki", "wysiwyg-wiki", 0, 0);
1081 @ <p>Enable what-you-see-is-what-you-get (WYSIWYG) editing of wiki pages.
1082 @ The WYSIWYG editor generates HTML instead of markup, which makes
1083
+1
--- src/tkt.c
+++ src/tkt.c
@@ -512,10 +512,11 @@
512512
getAllTicketFields();
513513
initializeVariablesFromDb();
514514
zScript = ticket_viewpage_code();
515515
if( P("showfields")!=0 ) showAllFields();
516516
if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br />\n", -1);
517
+ safe_html_context(DOCSRC_TICKET);
517518
Th_Render(zScript);
518519
if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
519520
520521
zFullName = db_text(0,
521522
"SELECT tkt_uuid FROM ticket"
522523
--- src/tkt.c
+++ src/tkt.c
@@ -512,10 +512,11 @@
512 getAllTicketFields();
513 initializeVariablesFromDb();
514 zScript = ticket_viewpage_code();
515 if( P("showfields")!=0 ) showAllFields();
516 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br />\n", -1);
 
517 Th_Render(zScript);
518 if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
519
520 zFullName = db_text(0,
521 "SELECT tkt_uuid FROM ticket"
522
--- src/tkt.c
+++ src/tkt.c
@@ -512,10 +512,11 @@
512 getAllTicketFields();
513 initializeVariablesFromDb();
514 zScript = ticket_viewpage_code();
515 if( P("showfields")!=0 ) showAllFields();
516 if( g.thTrace ) Th_Trace("BEGIN_TKTVIEW_SCRIPT<br />\n", -1);
517 safe_html_context(DOCSRC_TICKET);
518 Th_Render(zScript);
519 if( g.thTrace ) Th_Trace("END_TKTVIEW<br />\n", -1);
520
521 zFullName = db_text(0,
522 "SELECT tkt_uuid FROM ticket"
523
+17 -8
--- src/wiki.c
+++ src/wiki.c
@@ -191,17 +191,17 @@
191191
** text/x-markdown Markdown
192192
** anything else... Plain text
193193
**
194194
** If zMimetype is a null pointer, then use "text/x-fossil-wiki".
195195
*/
196
-void wiki_render_by_mimetype(Blob *pWiki, const char *zMimetype, int flags){
196
+void wiki_render_by_mimetype(Blob *pWiki, const char *zMimetype){
197197
if( zMimetype==0 || fossil_strcmp(zMimetype, "text/x-fossil-wiki")==0 ){
198
- wiki_convert(pWiki, 0, flags);
198
+ wiki_convert(pWiki, 0, 0);
199199
}else if( fossil_strcmp(zMimetype, "text/x-markdown")==0 ){
200200
Blob tail = BLOB_INITIALIZER;
201201
markdown_to_html(pWiki, 0, &tail);
202
- if( flags & WIKI_SAFE ) safe_html(&tail);
202
+ safe_html(&tail);
203203
@ %s(blob_str(&tail))
204204
blob_reset(&tail);
205205
}else{
206206
@ <pre class='textPlain'>
207207
@ %h(blob_str(pWiki))
@@ -223,11 +223,12 @@
223223
}else{
224224
style_submenu_element("Plain-Text", "%R/md_rules?txt=1");
225225
}
226226
blob_init(&x, builtin_text("markdown.md"), -1);
227227
blob_materialize(&x);
228
- wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown", 0);
228
+ safe_html_context(DOCSRC_TRUSTED);
229
+ wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown");
229230
blob_reset(&x);
230231
style_footer();
231232
}
232233
233234
/*
@@ -244,11 +245,12 @@
244245
}else{
245246
style_submenu_element("Plain-Text", "%R/wiki_rules?txt=1");
246247
}
247248
blob_init(&x, builtin_text("wiki.wiki"), -1);
248249
blob_materialize(&x);
249
- wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-fossil-wiki", 0);
250
+ safe_html_context(DOCSRC_TRUSTED);
251
+ wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-fossil-wiki");
250252
blob_reset(&x);
251253
style_footer();
252254
}
253255
254256
/*
@@ -561,11 +563,12 @@
561563
}
562564
if( zBody[0]==0 ){
563565
@ <i>This page has been deleted</i>
564566
}else{
565567
blob_init(&wiki, zBody, -1);
566
- wiki_render_by_mimetype(&wiki, zMimetype, 0);
568
+ safe_html_context(DOCSRC_WIKI);
569
+ wiki_render_by_mimetype(&wiki, zMimetype);
567570
blob_reset(&wiki);
568571
}
569572
attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
570573
manifest_destroy(pWiki);
571574
style_footer();
@@ -748,11 +751,12 @@
748751
blob_append(&wiki, zBody, -1);
749752
if( P("preview")!=0 ){
750753
havePreview = 1;
751754
if( zBody[0] ){
752755
@ Preview:<hr />
753
- wiki_render_by_mimetype(&wiki, zMimetype, 0);
756
+ safe_html_context(DOCSRC_WIKI);
757
+ wiki_render_by_mimetype(&wiki, zMimetype);
754758
@ <hr />
755759
blob_reset(&wiki);
756760
}
757761
}
758762
for(n=2, z=zBody; z[0]; z++){
@@ -1010,11 +1014,12 @@
10101014
if( P("preview")!=0 ){
10111015
Blob preview;
10121016
blob_zero(&preview);
10131017
appendRemark(&preview, zMimetype);
10141018
@ Preview:<hr />
1015
- wiki_render_by_mimetype(&preview, zMimetype, 0);
1019
+ safe_html_context(DOCSRC_WIKI);
1020
+ wiki_render_by_mimetype(&preview, zMimetype);
10161021
@ <hr />
10171022
blob_reset(&preview);
10181023
}
10191024
zUser = PD("u", g.zLogin);
10201025
form_begin(0, "%R/wikiappend");
@@ -1561,10 +1566,12 @@
15611566
** input blob before appending the output, which is
15621567
** different from wiki_convert() and htmlize_to_blob(), and
15631568
** precludes us simply appending the opening <html><body>
15641569
** part to the body
15651570
*/;
1571
+ safe_html_context(DOCSRC_WIKI);
1572
+ safe_html(&html);
15661573
}else if( fossil_strcmp(zMimetype, "text/plain")==0 ){
15671574
htmlize_to_blob(&html,zBody,i);
15681575
}else{
15691576
fossil_fatal("Unsupported MIME type '%s' for wiki page '%s'.",
15701577
zMimetype, pWiki->zWikiTitle );
@@ -1802,10 +1809,12 @@
18021809
}else{
18031810
wiki_section_label(zPrefix, zName, mFlags);
18041811
}
18051812
wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags);
18061813
@ <div class="accordion_panel">
1814
+ safe_html_context(DOCSRC_WIKI);
1815
+ safe_html(&tail);
18071816
convert_href_and_output(&tail);
18081817
@ </div>
18091818
blob_reset(&tail);
18101819
blob_reset(&title);
18111820
blob_reset(&markdown);
18121821
--- src/wiki.c
+++ src/wiki.c
@@ -191,17 +191,17 @@
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))
@@ -223,11 +223,12 @@
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 /*
@@ -244,11 +245,12 @@
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 /*
@@ -561,11 +563,12 @@
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, 0);
 
567 blob_reset(&wiki);
568 }
569 attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
570 manifest_destroy(pWiki);
571 style_footer();
@@ -748,11 +751,12 @@
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, 0);
 
754 @ <hr />
755 blob_reset(&wiki);
756 }
757 }
758 for(n=2, z=zBody; z[0]; z++){
@@ -1010,11 +1014,12 @@
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, 0);
 
1016 @ <hr />
1017 blob_reset(&preview);
1018 }
1019 zUser = PD("u", g.zLogin);
1020 form_begin(0, "%R/wikiappend");
@@ -1561,10 +1566,12 @@
1561 ** input blob before appending the output, which is
1562 ** different from wiki_convert() and htmlize_to_blob(), and
1563 ** precludes us simply appending the opening <html><body>
1564 ** part to the body
1565 */;
 
 
1566 }else if( fossil_strcmp(zMimetype, "text/plain")==0 ){
1567 htmlize_to_blob(&html,zBody,i);
1568 }else{
1569 fossil_fatal("Unsupported MIME type '%s' for wiki page '%s'.",
1570 zMimetype, pWiki->zWikiTitle );
@@ -1802,10 +1809,12 @@
1802 }else{
1803 wiki_section_label(zPrefix, zName, mFlags);
1804 }
1805 wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags);
1806 @ <div class="accordion_panel">
 
 
1807 convert_href_and_output(&tail);
1808 @ </div>
1809 blob_reset(&tail);
1810 blob_reset(&title);
1811 blob_reset(&markdown);
1812
--- src/wiki.c
+++ src/wiki.c
@@ -191,17 +191,17 @@
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){
197 if( zMimetype==0 || fossil_strcmp(zMimetype, "text/x-fossil-wiki")==0 ){
198 wiki_convert(pWiki, 0, 0);
199 }else if( fossil_strcmp(zMimetype, "text/x-markdown")==0 ){
200 Blob tail = BLOB_INITIALIZER;
201 markdown_to_html(pWiki, 0, &tail);
202 safe_html(&tail);
203 @ %s(blob_str(&tail))
204 blob_reset(&tail);
205 }else{
206 @ <pre class='textPlain'>
207 @ %h(blob_str(pWiki))
@@ -223,11 +223,12 @@
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 safe_html_context(DOCSRC_TRUSTED);
229 wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-markdown");
230 blob_reset(&x);
231 style_footer();
232 }
233
234 /*
@@ -244,11 +245,12 @@
245 }else{
246 style_submenu_element("Plain-Text", "%R/wiki_rules?txt=1");
247 }
248 blob_init(&x, builtin_text("wiki.wiki"), -1);
249 blob_materialize(&x);
250 safe_html_context(DOCSRC_TRUSTED);
251 wiki_render_by_mimetype(&x, fTxt ? "text/plain" : "text/x-fossil-wiki");
252 blob_reset(&x);
253 style_footer();
254 }
255
256 /*
@@ -561,11 +563,12 @@
563 }
564 if( zBody[0]==0 ){
565 @ <i>This page has been deleted</i>
566 }else{
567 blob_init(&wiki, zBody, -1);
568 safe_html_context(DOCSRC_WIKI);
569 wiki_render_by_mimetype(&wiki, zMimetype);
570 blob_reset(&wiki);
571 }
572 attachment_list(zPageName, "<hr /><h2>Attachments:</h2><ul>");
573 manifest_destroy(pWiki);
574 style_footer();
@@ -748,11 +751,12 @@
751 blob_append(&wiki, zBody, -1);
752 if( P("preview")!=0 ){
753 havePreview = 1;
754 if( zBody[0] ){
755 @ Preview:<hr />
756 safe_html_context(DOCSRC_WIKI);
757 wiki_render_by_mimetype(&wiki, zMimetype);
758 @ <hr />
759 blob_reset(&wiki);
760 }
761 }
762 for(n=2, z=zBody; z[0]; z++){
@@ -1010,11 +1014,12 @@
1014 if( P("preview")!=0 ){
1015 Blob preview;
1016 blob_zero(&preview);
1017 appendRemark(&preview, zMimetype);
1018 @ Preview:<hr />
1019 safe_html_context(DOCSRC_WIKI);
1020 wiki_render_by_mimetype(&preview, zMimetype);
1021 @ <hr />
1022 blob_reset(&preview);
1023 }
1024 zUser = PD("u", g.zLogin);
1025 form_begin(0, "%R/wikiappend");
@@ -1561,10 +1566,12 @@
1566 ** input blob before appending the output, which is
1567 ** different from wiki_convert() and htmlize_to_blob(), and
1568 ** precludes us simply appending the opening <html><body>
1569 ** part to the body
1570 */;
1571 safe_html_context(DOCSRC_WIKI);
1572 safe_html(&html);
1573 }else if( fossil_strcmp(zMimetype, "text/plain")==0 ){
1574 htmlize_to_blob(&html,zBody,i);
1575 }else{
1576 fossil_fatal("Unsupported MIME type '%s' for wiki page '%s'.",
1577 zMimetype, pWiki->zWikiTitle );
@@ -1802,10 +1809,12 @@
1809 }else{
1810 wiki_section_label(zPrefix, zName, mFlags);
1811 }
1812 wiki_submenu_to_edit_wiki(zPrefix, zName, mFlags);
1813 @ <div class="accordion_panel">
1814 safe_html_context(DOCSRC_WIKI);
1815 safe_html(&tail);
1816 convert_href_and_output(&tail);
1817 @ </div>
1818 blob_reset(&tail);
1819 blob_reset(&title);
1820 blob_reset(&markdown);
1821
+52 -3
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1811,11 +1811,11 @@
18111811
** Usage: %fossil test-markdown-render FILE ...
18121812
**
18131813
** Render markdown in FILE as HTML on stdout.
18141814
** Options:
18151815
**
1816
-** --safe Do "safe-html" rendering.
1816
+** --safe Restrict the output to use only "safe" HTML
18171817
*/
18181818
void test_markdown_render(void){
18191819
Blob in, out;
18201820
int i;
18211821
int bSafe = 0;
@@ -1827,11 +1827,12 @@
18271827
blob_read_from_file(&in, g.argv[i], ExtFILE);
18281828
if( g.argc>3 ){
18291829
fossil_print("<!------ %h ------->\n", g.argv[i]);
18301830
}
18311831
markdown_to_html(&in, 0, &out);
1832
- if( bSafe ) safe_html(&out);
1832
+ safe_html_context( bSafe ? DOCSRC_UNTRUSTED : DOCSRC_TRUSTED );
1833
+ safe_html(&out);
18331834
blob_write_to_file(&out, "-");
18341835
blob_reset(&in);
18351836
blob_reset(&out);
18361837
}
18371838
}
@@ -2569,10 +2570,58 @@
25692570
}
25702571
html_tagstack_pop(&s, pBlob, 0);
25712572
html_tagstack_clear(&s);
25722573
zHtml[nHtml] = cLast;
25732574
}
2575
+
2576
+/*
2577
+** This local variable is true if the safe_html() function is enabled.
2578
+** In other words, this is true if the output of Markdown should be
2579
+** restricted to use only "safe" HTML.
2580
+*/
2581
+static int safeHtmlEnable = 1;
2582
+
2583
+
2584
+#if INTERFACE
2585
+/*
2586
+** Allowed values for the eTrust parameter to safe_html_context().
2587
+*/
2588
+#define DOCSRC_FILE 1 /* Document is a checked-in file */
2589
+#define DOCSRC_FORUM 2 /* Document is a forum post */
2590
+#define DOCSRC_TICKET 3 /* Document is a ticket comment */
2591
+#define DOCSRC_WIKI 4 /* Document is a wiki page */
2592
+#define DOCSRC_TRUSTED 5 /* safe_html() is always a no-op */
2593
+#define DOCSRC_UNTRUSTED 6 /* safe_html() is always enabled */
2594
+#endif /* INTERFACE */
2595
+
2596
+
2597
+/*
2598
+** Specify the context in which a markdown document with potentially
2599
+** unsafe HTML will be rendered.
2600
+*/
2601
+void safe_html_context(int eTrust){
2602
+ static const char *zSafeHtmlSetting = 0;
2603
+ char cPerm = 0;
2604
+ if( eTrust==DOCSRC_TRUSTED ){
2605
+ safeHtmlEnable = 0;
2606
+ return;
2607
+ }
2608
+ if( eTrust==DOCSRC_UNTRUSTED ){
2609
+ safeHtmlEnable = 1;
2610
+ return;
2611
+ }
2612
+ if( zSafeHtmlSetting==0 ){
2613
+ zSafeHtmlSetting = db_get("safe-html", "");
2614
+ }
2615
+ switch( eTrust ){
2616
+ case DOCSRC_FILE: cPerm = 'b'; break;
2617
+ case DOCSRC_FORUM: cPerm = 'f'; break;
2618
+ case DOCSRC_TICKET: cPerm = 't'; break;
2619
+ case DOCSRC_WIKI: cPerm = 'w'; break;
2620
+ }
2621
+ safeHtmlEnable = (strchr(zSafeHtmlSetting,cPerm)==0);
2622
+}
25742623
25752624
/*
25762625
** The input blob contains HTML. If safe-html is enabled, then
25772626
** convert the input into "safe HTML". The following modifications
25782627
** are made:
@@ -2603,11 +2652,11 @@
26032652
Blob out; /* Holding area for the revised text during construction */
26042653
char *z; /* Original input text */
26052654
int n; /* Number of bytes in the original input text */
26062655
int k;
26072656
2608
- /* if( safeHtml==0 ) return; TBD: Always used at this time */
2657
+ if( safeHtmlEnable==0 ) return;
26092658
z = blob_str(in);
26102659
n = blob_size(in);
26112660
blob_init(&out, 0, 0);
26122661
while( fossil_isspace(z[0]) ){ z++; n--; }
26132662
for(k=n-1; k>5 && fossil_isspace(z[k]); k--){}
26142663
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1811,11 +1811,11 @@
1811 ** Usage: %fossil test-markdown-render FILE ...
1812 **
1813 ** Render markdown in FILE as HTML on stdout.
1814 ** Options:
1815 **
1816 ** --safe Do "safe-html" rendering.
1817 */
1818 void test_markdown_render(void){
1819 Blob in, out;
1820 int i;
1821 int bSafe = 0;
@@ -1827,11 +1827,12 @@
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 }
@@ -2569,10 +2570,58 @@
2569 }
2570 html_tagstack_pop(&s, pBlob, 0);
2571 html_tagstack_clear(&s);
2572 zHtml[nHtml] = cLast;
2573 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2574
2575 /*
2576 ** The input blob contains HTML. If safe-html is enabled, then
2577 ** convert the input into "safe HTML". The following modifications
2578 ** are made:
@@ -2603,11 +2652,11 @@
2603 Blob out; /* Holding area for the revised text during construction */
2604 char *z; /* Original input text */
2605 int n; /* Number of bytes in the original input text */
2606 int k;
2607
2608 /* if( safeHtml==0 ) return; TBD: Always used at this time */
2609 z = blob_str(in);
2610 n = blob_size(in);
2611 blob_init(&out, 0, 0);
2612 while( fossil_isspace(z[0]) ){ z++; n--; }
2613 for(k=n-1; k>5 && fossil_isspace(z[k]); k--){}
2614
--- src/wikiformat.c
+++ src/wikiformat.c
@@ -1811,11 +1811,11 @@
1811 ** Usage: %fossil test-markdown-render FILE ...
1812 **
1813 ** Render markdown in FILE as HTML on stdout.
1814 ** Options:
1815 **
1816 ** --safe Restrict the output to use only "safe" HTML
1817 */
1818 void test_markdown_render(void){
1819 Blob in, out;
1820 int i;
1821 int bSafe = 0;
@@ -1827,11 +1827,12 @@
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 safe_html_context( bSafe ? DOCSRC_UNTRUSTED : DOCSRC_TRUSTED );
1833 safe_html(&out);
1834 blob_write_to_file(&out, "-");
1835 blob_reset(&in);
1836 blob_reset(&out);
1837 }
1838 }
@@ -2569,10 +2570,58 @@
2570 }
2571 html_tagstack_pop(&s, pBlob, 0);
2572 html_tagstack_clear(&s);
2573 zHtml[nHtml] = cLast;
2574 }
2575
2576 /*
2577 ** This local variable is true if the safe_html() function is enabled.
2578 ** In other words, this is true if the output of Markdown should be
2579 ** restricted to use only "safe" HTML.
2580 */
2581 static int safeHtmlEnable = 1;
2582
2583
2584 #if INTERFACE
2585 /*
2586 ** Allowed values for the eTrust parameter to safe_html_context().
2587 */
2588 #define DOCSRC_FILE 1 /* Document is a checked-in file */
2589 #define DOCSRC_FORUM 2 /* Document is a forum post */
2590 #define DOCSRC_TICKET 3 /* Document is a ticket comment */
2591 #define DOCSRC_WIKI 4 /* Document is a wiki page */
2592 #define DOCSRC_TRUSTED 5 /* safe_html() is always a no-op */
2593 #define DOCSRC_UNTRUSTED 6 /* safe_html() is always enabled */
2594 #endif /* INTERFACE */
2595
2596
2597 /*
2598 ** Specify the context in which a markdown document with potentially
2599 ** unsafe HTML will be rendered.
2600 */
2601 void safe_html_context(int eTrust){
2602 static const char *zSafeHtmlSetting = 0;
2603 char cPerm = 0;
2604 if( eTrust==DOCSRC_TRUSTED ){
2605 safeHtmlEnable = 0;
2606 return;
2607 }
2608 if( eTrust==DOCSRC_UNTRUSTED ){
2609 safeHtmlEnable = 1;
2610 return;
2611 }
2612 if( zSafeHtmlSetting==0 ){
2613 zSafeHtmlSetting = db_get("safe-html", "");
2614 }
2615 switch( eTrust ){
2616 case DOCSRC_FILE: cPerm = 'b'; break;
2617 case DOCSRC_FORUM: cPerm = 'f'; break;
2618 case DOCSRC_TICKET: cPerm = 't'; break;
2619 case DOCSRC_WIKI: cPerm = 'w'; break;
2620 }
2621 safeHtmlEnable = (strchr(zSafeHtmlSetting,cPerm)==0);
2622 }
2623
2624 /*
2625 ** The input blob contains HTML. If safe-html is enabled, then
2626 ** convert the input into "safe HTML". The following modifications
2627 ** are made:
@@ -2603,11 +2652,11 @@
2652 Blob out; /* Holding area for the revised text during construction */
2653 char *z; /* Original input text */
2654 int n; /* Number of bytes in the original input text */
2655 int k;
2656
2657 if( safeHtmlEnable==0 ) return;
2658 z = blob_str(in);
2659 n = blob_size(in);
2660 blob_init(&out, 0, 0);
2661 while( fossil_isspace(z[0]) ){ z++; n--; }
2662 for(k=n-1; k>5 && fossil_isspace(z[k]); k--){}
2663

Keyboard Shortcuts

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