Fossil SCM

Merge the latest changes from trunk into sec2020.

drh 2020-08-21 01:01 sec2020 merge
Commit 1d61aae3143a4c09262f73f873b95864d40239e07074007a8021abc0910a6cd5
+5 -2
--- auto.def
+++ auto.def
@@ -176,12 +176,15 @@
176176
}
177177
if {!$ok} {
178178
user-error "unable to compile SQLite compatibility test program"
179179
}
180180
set err [catch {exec-with-stderr ./conftest__} result errinfo]
181
- if {$err} {
182
- user-error $result
181
+ if {[get-define build] eq [get-define host]} {
182
+ set err [catch {exec-with-stderr ./conftest__} result errinfo]
183
+ if {$err} {
184
+ user-error $result
185
+ }
183186
}
184187
file delete ./conftest__
185188
}
186189
test_system_sqlite
187190
188191
--- auto.def
+++ auto.def
@@ -176,12 +176,15 @@
176 }
177 if {!$ok} {
178 user-error "unable to compile SQLite compatibility test program"
179 }
180 set err [catch {exec-with-stderr ./conftest__} result errinfo]
181 if {$err} {
182 user-error $result
 
 
 
183 }
184 file delete ./conftest__
185 }
186 test_system_sqlite
187
188
--- auto.def
+++ auto.def
@@ -176,12 +176,15 @@
176 }
177 if {!$ok} {
178 user-error "unable to compile SQLite compatibility test program"
179 }
180 set err [catch {exec-with-stderr ./conftest__} result errinfo]
181 if {[get-define build] eq [get-define host]} {
182 set err [catch {exec-with-stderr ./conftest__} result errinfo]
183 if {$err} {
184 user-error $result
185 }
186 }
187 file delete ./conftest__
188 }
189 test_system_sqlite
190
191
+1 -1
--- src/copybtn.js
+++ src/copybtn.js
@@ -80,11 +80,11 @@
8080
}.bind(null,this.id),400);
8181
}
8282
/* Create a temporary <textarea> element and copy the contents to clipboard. */
8383
function copyTextToClipboard(text){
8484
if( window.clipboardData && window.clipboardData.setData ){
85
- clipboardData.setData('Text',text);
85
+ window.clipboardData.setData('Text',text);
8686
}else{
8787
var x = document.createElement("textarea");
8888
x.style.position = 'fixed';
8989
x.value = text;
9090
document.body.appendChild(x);
9191
--- src/copybtn.js
+++ src/copybtn.js
@@ -80,11 +80,11 @@
80 }.bind(null,this.id),400);
81 }
82 /* Create a temporary <textarea> element and copy the contents to clipboard. */
83 function copyTextToClipboard(text){
84 if( window.clipboardData && window.clipboardData.setData ){
85 clipboardData.setData('Text',text);
86 }else{
87 var x = document.createElement("textarea");
88 x.style.position = 'fixed';
89 x.value = text;
90 document.body.appendChild(x);
91
--- src/copybtn.js
+++ src/copybtn.js
@@ -80,11 +80,11 @@
80 }.bind(null,this.id),400);
81 }
82 /* Create a temporary <textarea> element and copy the contents to clipboard. */
83 function copyTextToClipboard(text){
84 if( window.clipboardData && window.clipboardData.setData ){
85 window.clipboardData.setData('Text',text);
86 }else{
87 var x = document.createElement("textarea");
88 x.style.position = 'fixed';
89 x.value = text;
90 document.body.appendChild(x);
91
+1 -1
--- src/default.css
+++ src/default.css
@@ -1250,11 +1250,11 @@
12501250
padding: 0.2em 1em;
12511251
border: 1px solid black;
12521252
border-radius: 0.25em;
12531253
position: absolute;
12541254
display: inline-block;
1255
- z-index: 100;
1255
+ z-index: 19/*below default skin's hamburger popup*/;
12561256
box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.75);
12571257
background-color: inherit;
12581258
}
12591259
12601260
.fossil-toast-message {
12611261
--- src/default.css
+++ src/default.css
@@ -1250,11 +1250,11 @@
1250 padding: 0.2em 1em;
1251 border: 1px solid black;
1252 border-radius: 0.25em;
1253 position: absolute;
1254 display: inline-block;
1255 z-index: 100;
1256 box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.75);
1257 background-color: inherit;
1258 }
1259
1260 .fossil-toast-message {
1261
--- src/default.css
+++ src/default.css
@@ -1250,11 +1250,11 @@
1250 padding: 0.2em 1em;
1251 border: 1px solid black;
1252 border-radius: 0.25em;
1253 position: absolute;
1254 display: inline-block;
1255 z-index: 19/*below default skin's hamburger popup*/;
1256 box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.75);
1257 background-color: inherit;
1258 }
1259
1260 .fossil-toast-message {
1261
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -521,11 +521,11 @@
521521
Attempts to copy the given text to the system clipboard. Returns
522522
true if it succeeds, else false.
523523
*/
524524
dom.copyTextToClipboard = function(text){
525525
if( window.clipboardData && window.clipboardData.setData ){
526
- clipboardData.setData('Text',text);
526
+ window.clipboardData.setData('Text',text);
527527
return true;
528528
}else{
529529
const x = document.createElement("textarea");
530530
x.style.position = 'fixed';
531531
x.value = text;
532532
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -521,11 +521,11 @@
521 Attempts to copy the given text to the system clipboard. Returns
522 true if it succeeds, else false.
523 */
524 dom.copyTextToClipboard = function(text){
525 if( window.clipboardData && window.clipboardData.setData ){
526 clipboardData.setData('Text',text);
527 return true;
528 }else{
529 const x = document.createElement("textarea");
530 x.style.position = 'fixed';
531 x.value = text;
532
--- src/fossil.dom.js
+++ src/fossil.dom.js
@@ -521,11 +521,11 @@
521 Attempts to copy the given text to the system clipboard. Returns
522 true if it succeeds, else false.
523 */
524 dom.copyTextToClipboard = function(text){
525 if( window.clipboardData && window.clipboardData.setData ){
526 window.clipboardData.setData('Text',text);
527 return true;
528 }else{
529 const x = document.createElement("textarea");
530 x.style.position = 'fixed';
531 x.value = text;
532
--- src/fossil.numbered-lines.js
+++ src/fossil.numbered-lines.js
@@ -25,11 +25,11 @@
2525
.replace(/&?\bln=[^&]*/,'') /* inbound line number/range */
2626
.replace('?&','?'),
2727
start: 0, end: 0
2828
};
2929
30
- const lineTip = new fossil.PopupWidget({
30
+ const lineTip = new F.PopupWidget({
3131
style: {
3232
cursor: 'pointer'
3333
},
3434
refresh: function(){
3535
const link = this.state.link;
3636
--- src/fossil.numbered-lines.js
+++ src/fossil.numbered-lines.js
@@ -25,11 +25,11 @@
25 .replace(/&?\bln=[^&]*/,'') /* inbound line number/range */
26 .replace('?&','?'),
27 start: 0, end: 0
28 };
29
30 const lineTip = new fossil.PopupWidget({
31 style: {
32 cursor: 'pointer'
33 },
34 refresh: function(){
35 const link = this.state.link;
36
--- src/fossil.numbered-lines.js
+++ src/fossil.numbered-lines.js
@@ -25,11 +25,11 @@
25 .replace(/&?\bln=[^&]*/,'') /* inbound line number/range */
26 .replace('?&','?'),
27 start: 0, end: 0
28 };
29
30 const lineTip = new F.PopupWidget({
31 style: {
32 cursor: 'pointer'
33 },
34 refresh: function(){
35 const link = this.state.link;
36
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -638,11 +638,11 @@
638638
};
639639
640640
F.onPageLoad(function() {
641641
P.base = {tag: E('base')};
642642
P.base.originalHref = P.base.tag.href;
643
- P.tabs = new fossil.TabManager('#fileedit-tabs');
643
+ P.tabs = new F.TabManager('#fileedit-tabs');
644644
P.e = { /* various DOM elements we work with... */
645645
taEditor: E('#fileedit-content-editor'),
646646
taCommentSmall: E('#fileedit-comment'),
647647
taCommentBig: E('#fileedit-comment-big'),
648648
taComment: undefined/*gets set to one of taComment{Big,Small}*/,
@@ -1142,11 +1142,11 @@
11421142
mimetype: P.finfo.mimetype,
11431143
element: P.e.previewTarget
11441144
});
11451145
},
11461146
onerror: (e)=>{
1147
- fossil.fetch.onerror(e);
1147
+ F.fetch.onerror(e);
11481148
callback("Error fetching preview: "+e);
11491149
}
11501150
});
11511151
return this;
11521152
};
11531153
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -638,11 +638,11 @@
638 };
639
640 F.onPageLoad(function() {
641 P.base = {tag: E('base')};
642 P.base.originalHref = P.base.tag.href;
643 P.tabs = new fossil.TabManager('#fileedit-tabs');
644 P.e = { /* various DOM elements we work with... */
645 taEditor: E('#fileedit-content-editor'),
646 taCommentSmall: E('#fileedit-comment'),
647 taCommentBig: E('#fileedit-comment-big'),
648 taComment: undefined/*gets set to one of taComment{Big,Small}*/,
@@ -1142,11 +1142,11 @@
1142 mimetype: P.finfo.mimetype,
1143 element: P.e.previewTarget
1144 });
1145 },
1146 onerror: (e)=>{
1147 fossil.fetch.onerror(e);
1148 callback("Error fetching preview: "+e);
1149 }
1150 });
1151 return this;
1152 };
1153
--- src/fossil.page.fileedit.js
+++ src/fossil.page.fileedit.js
@@ -638,11 +638,11 @@
638 };
639
640 F.onPageLoad(function() {
641 P.base = {tag: E('base')};
642 P.base.originalHref = P.base.tag.href;
643 P.tabs = new F.TabManager('#fileedit-tabs');
644 P.e = { /* various DOM elements we work with... */
645 taEditor: E('#fileedit-content-editor'),
646 taCommentSmall: E('#fileedit-comment'),
647 taCommentBig: E('#fileedit-comment-big'),
648 taComment: undefined/*gets set to one of taComment{Big,Small}*/,
@@ -1142,11 +1142,11 @@
1142 mimetype: P.finfo.mimetype,
1143 element: P.e.previewTarget
1144 });
1145 },
1146 onerror: (e)=>{
1147 F.fetch.onerror(e);
1148 callback("Error fetching preview: "+e);
1149 }
1150 });
1151 return this;
1152 };
1153
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -1,9 +1,9 @@
11
(function(F/*the fossil object*/){
22
"use strict";
33
/* JS code for /forumpage and friends. Requires fossil.dom. */
4
- const P = fossil.page, D = fossil.dom;
4
+ const P = F.page, D = F.dom;
55
66
F.onPageLoad(function(){
77
const scrollbarIsVisible = (e)=>e.scrollHeight > e.clientHeight;
88
/* Returns an event handler which implements the post expand/collapse toggle
99
on contentElem when the given widget is activated. */
1010
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -1,9 +1,9 @@
1 (function(F/*the fossil object*/){
2 "use strict";
3 /* JS code for /forumpage and friends. Requires fossil.dom. */
4 const P = fossil.page, D = fossil.dom;
5
6 F.onPageLoad(function(){
7 const scrollbarIsVisible = (e)=>e.scrollHeight > e.clientHeight;
8 /* Returns an event handler which implements the post expand/collapse toggle
9 on contentElem when the given widget is activated. */
10
--- src/fossil.page.forumpost.js
+++ src/fossil.page.forumpost.js
@@ -1,9 +1,9 @@
1 (function(F/*the fossil object*/){
2 "use strict";
3 /* JS code for /forumpage and friends. Requires fossil.dom. */
4 const P = F.page, D = F.dom;
5
6 F.onPageLoad(function(){
7 const scrollbarIsVisible = (e)=>e.scrollHeight > e.clientHeight;
8 /* Returns an event handler which implements the post expand/collapse toggle
9 on contentElem when the given widget is activated. */
10
--- src/fossil.page.wikiedit.js
+++ src/fossil.page.wikiedit.js
@@ -855,11 +855,11 @@
855855
diff: E('#wikiedit-tab-diff'),
856856
misc: E('#wikiedit-tab-misc')
857857
//commit: E('#wikiedit-tab-commit')
858858
}
859859
};
860
- P.tabs = new fossil.TabManager(D.clearElement(P.e.tabContainer));
860
+ P.tabs = new F.TabManager(D.clearElement(P.e.tabContainer));
861861
P.tabs.e.container.insertBefore(
862862
/* Move the status bar between the tab buttons and
863863
tab panels. Seems to be the best fit in terms of
864864
functionality and visibility. */
865865
E('#fossil-status-bar'), P.tabs.e.tabs
@@ -1322,11 +1322,11 @@
13221322
mimetype: mimetype,
13231323
element: P.e.previewTarget
13241324
});
13251325
},
13261326
onerror: (e)=>{
1327
- fossil.fetch.onerror(e);
1327
+ F.fetch.onerror(e);
13281328
callback("Error fetching preview: "+e);
13291329
}
13301330
});
13311331
return this;
13321332
};
13331333
--- src/fossil.page.wikiedit.js
+++ src/fossil.page.wikiedit.js
@@ -855,11 +855,11 @@
855 diff: E('#wikiedit-tab-diff'),
856 misc: E('#wikiedit-tab-misc')
857 //commit: E('#wikiedit-tab-commit')
858 }
859 };
860 P.tabs = new fossil.TabManager(D.clearElement(P.e.tabContainer));
861 P.tabs.e.container.insertBefore(
862 /* Move the status bar between the tab buttons and
863 tab panels. Seems to be the best fit in terms of
864 functionality and visibility. */
865 E('#fossil-status-bar'), P.tabs.e.tabs
@@ -1322,11 +1322,11 @@
1322 mimetype: mimetype,
1323 element: P.e.previewTarget
1324 });
1325 },
1326 onerror: (e)=>{
1327 fossil.fetch.onerror(e);
1328 callback("Error fetching preview: "+e);
1329 }
1330 });
1331 return this;
1332 };
1333
--- src/fossil.page.wikiedit.js
+++ src/fossil.page.wikiedit.js
@@ -855,11 +855,11 @@
855 diff: E('#wikiedit-tab-diff'),
856 misc: E('#wikiedit-tab-misc')
857 //commit: E('#wikiedit-tab-commit')
858 }
859 };
860 P.tabs = new F.TabManager(D.clearElement(P.e.tabContainer));
861 P.tabs.e.container.insertBefore(
862 /* Move the status bar between the tab buttons and
863 tab panels. Seems to be the best fit in terms of
864 functionality and visibility. */
865 E('#fossil-status-bar'), P.tabs.e.tabs
@@ -1322,11 +1322,11 @@
1322 mimetype: mimetype,
1323 element: P.e.previewTarget
1324 });
1325 },
1326 onerror: (e)=>{
1327 F.fetch.onerror(e);
1328 callback("Error fetching preview: "+e);
1329 }
1330 });
1331 return this;
1332 };
1333
--- src/fossil.popupwidget.js
+++ src/fossil.popupwidget.js
@@ -176,12 +176,12 @@
176176
this.e.style.top = y+"px";
177177
}
178178
D.removeClass(this.e, 'hidden');
179179
}else{
180180
D.addClass(this.e, 'hidden');
181
- delete this.e.style.removeProperty('left');
182
- delete this.e.style.removeProperty('top');
181
+ this.e.style.removeProperty('left');
182
+ this.e.style.removeProperty('top');
183183
}
184184
return this;
185185
},
186186
187187
hide: function(){return this.show(false)}
188188
--- src/fossil.popupwidget.js
+++ src/fossil.popupwidget.js
@@ -176,12 +176,12 @@
176 this.e.style.top = y+"px";
177 }
178 D.removeClass(this.e, 'hidden');
179 }else{
180 D.addClass(this.e, 'hidden');
181 delete this.e.style.removeProperty('left');
182 delete this.e.style.removeProperty('top');
183 }
184 return this;
185 },
186
187 hide: function(){return this.show(false)}
188
--- src/fossil.popupwidget.js
+++ src/fossil.popupwidget.js
@@ -176,12 +176,12 @@
176 this.e.style.top = y+"px";
177 }
178 D.removeClass(this.e, 'hidden');
179 }else{
180 D.addClass(this.e, 'hidden');
181 this.e.style.removeProperty('left');
182 this.e.style.removeProperty('top');
183 }
184 return this;
185 },
186
187 hide: function(){return this.show(false)}
188
--- src/fossil.storage.js
+++ src/fossil.storage.js
@@ -89,11 +89,11 @@
8989
page-instance-local proxy, if neither one is availble.
9090
9191
Which exact storage implementation is uses is unspecified, and
9292
apps must not rely on it.
9393
*/
94
- fossil.storage = {
94
+ F.storage = {
9595
storageKeyPrefix: storageKeyPrefix,
9696
/** Sets the storage key k to value v, implicitly converting
9797
it to a string. */
9898
set: (k,v)=>$storage.setItem(storageKeyPrefix+k,v),
9999
/** Sets storage key k to JSON.stringify(v). */
100100
--- src/fossil.storage.js
+++ src/fossil.storage.js
@@ -89,11 +89,11 @@
89 page-instance-local proxy, if neither one is availble.
90
91 Which exact storage implementation is uses is unspecified, and
92 apps must not rely on it.
93 */
94 fossil.storage = {
95 storageKeyPrefix: storageKeyPrefix,
96 /** Sets the storage key k to value v, implicitly converting
97 it to a string. */
98 set: (k,v)=>$storage.setItem(storageKeyPrefix+k,v),
99 /** Sets storage key k to JSON.stringify(v). */
100
--- src/fossil.storage.js
+++ src/fossil.storage.js
@@ -89,11 +89,11 @@
89 page-instance-local proxy, if neither one is availble.
90
91 Which exact storage implementation is uses is unspecified, and
92 apps must not rely on it.
93 */
94 F.storage = {
95 storageKeyPrefix: storageKeyPrefix,
96 /** Sets the storage key k to value v, implicitly converting
97 it to a string. */
98 set: (k,v)=>$storage.setItem(storageKeyPrefix+k,v),
99 /** Sets storage key k to JSON.stringify(v). */
100
+5 -3
--- src/info.c
+++ src/info.c
@@ -2306,17 +2306,19 @@
23062306
const char *zPath;
23072307
Blob path;
23082308
blob_zero(&path);
23092309
hyperlinked_path(zName, &path, zCI, "dir", "", LINKPATH_FINFO);
23102310
zPath = blob_str(&path);
2311
- @ <h2>File %s(zPath) \
2311
+ @ <h2>File %s(zPath) artifact \
2312
+ style_copy_button(1,"hash-fid",0,0,"%z%S</a> ",
2313
+ href("%R/info/%s",zUuid),zUuid);
23122314
if( isBranchCI ){
23132315
@ on branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a></h2>
23142316
}else if( isSymbolicCI ){
2315
- @ as of check-in %z(href("%R/info/%!S",zCIUuid))%s(zCI)</a></h2>
2317
+ @ part of check-in %z(href("%R/info/%!S",zCIUuid))%s(zCI)</a></h2>
23162318
}else{
2317
- @ as of check-in [%z(href("%R/info/%!S",zCIUuid))%S(zCIUuid)</a>]</h2>
2319
+ @ part of check-in %z(href("%R/info/%!S",zCIUuid))%S(zCIUuid)</a></h2>
23182320
}
23192321
blob_reset(&path);
23202322
}
23212323
style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
23222324
style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
23232325
--- src/info.c
+++ src/info.c
@@ -2306,17 +2306,19 @@
2306 const char *zPath;
2307 Blob path;
2308 blob_zero(&path);
2309 hyperlinked_path(zName, &path, zCI, "dir", "", LINKPATH_FINFO);
2310 zPath = blob_str(&path);
2311 @ <h2>File %s(zPath) \
 
 
2312 if( isBranchCI ){
2313 @ on branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a></h2>
2314 }else if( isSymbolicCI ){
2315 @ as of check-in %z(href("%R/info/%!S",zCIUuid))%s(zCI)</a></h2>
2316 }else{
2317 @ as of check-in [%z(href("%R/info/%!S",zCIUuid))%S(zCIUuid)</a>]</h2>
2318 }
2319 blob_reset(&path);
2320 }
2321 style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
2322 style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
2323
--- src/info.c
+++ src/info.c
@@ -2306,17 +2306,19 @@
2306 const char *zPath;
2307 Blob path;
2308 blob_zero(&path);
2309 hyperlinked_path(zName, &path, zCI, "dir", "", LINKPATH_FINFO);
2310 zPath = blob_str(&path);
2311 @ <h2>File %s(zPath) artifact \
2312 style_copy_button(1,"hash-fid",0,0,"%z%S</a> ",
2313 href("%R/info/%s",zUuid),zUuid);
2314 if( isBranchCI ){
2315 @ on branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a></h2>
2316 }else if( isSymbolicCI ){
2317 @ part of check-in %z(href("%R/info/%!S",zCIUuid))%s(zCI)</a></h2>
2318 }else{
2319 @ part of check-in %z(href("%R/info/%!S",zCIUuid))%S(zCIUuid)</a></h2>
2320 }
2321 blob_reset(&path);
2322 }
2323 style_submenu_element("Artifact", "%R/artifact/%S", zUuid);
2324 style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T",
2325
+34 -11
--- src/wiki.c
+++ src/wiki.c
@@ -725,12 +725,24 @@
725725
** Loads the given wiki page, sets the response type to
726726
** application/json, and emits it as a JSON object. If zPageName is a
727727
** sandbox page then a "fake" object is emitted, as the wikiajax API
728728
** does not permit saving the sandbox.
729729
**
730
-** Returns true on success, false on error, and on error it
731
-** queues up a JSON-format error response.
730
+** If includeLeadingComma is true then a comma will be emitted
731
+** preceeding the object. This parameter is a bit of a hack to allow
732
+** wiki page list generation to recover from an unusual (so far unique
733
+** to one repo) error mode.
734
+**
735
+** Returns true on success, false on error. Its behaviour on error
736
+** depends on the 4th argument: if it's true, this function simply
737
+** returns false, else it queues up a JSON response and returns false.
738
+** The intention of this flag is to avoid a weird corner case seen, so
739
+** far, only on the main fossil repo (not clones of it) in which
740
+** loading fails for a page named "Security Desk Technician". The
741
+** hypothesis is that that page was once shunned on the core repo, but
742
+** a reference to it still exists in the tables from which we pull the
743
+** wiki list.
732744
**
733745
** Output JSON format:
734746
**
735747
** { name: "page name",
736748
** type: "normal" | "tag" | "checkin" | "branch" | "sandbox",
@@ -743,18 +755,23 @@
743755
** }
744756
**
745757
** If includeContent is false then the content member is elided.
746758
*/
747759
static int wiki_ajax_emit_page_object(const char *zPageName,
748
- int includeContent){
760
+ int includeContent,
761
+ int includeLeadingComma,
762
+ int ignoreLoadError){
749763
Manifest * pWiki = 0;
750764
char * zUuid;
751765
752766
if( is_sandbox(zPageName) ){
753767
char * zMimetype =
754768
db_get("sandbox-mimetype","text/x-fossil-wiki");
755769
char * zBody = db_get("sandbox","");
770
+ if(includeLeadingComma){
771
+ CX(",");
772
+ }
756773
CX("{\"name\": %!j, \"type\": \"sandbox\", "
757774
"\"mimetype\": %!j, \"version\": null, \"parent\": null",
758775
zPageName, zMimetype);
759776
if(includeContent){
760777
CX(", \"content\": %!j",
@@ -763,14 +780,19 @@
763780
CX("}");
764781
fossil_free(zMimetype);
765782
fossil_free(zBody);
766783
return 1;
767784
}else if( !wiki_fetch_by_name(zPageName, 0, 0, &pWiki) ){
768
- ajax_route_error(404, "Wiki page could not be loaded: %s",
769
- zPageName);
785
+ if(ignoreLoadError!=0){
786
+ ajax_route_error(404, "Wiki page could not be loaded: %s",
787
+ zPageName);
788
+ }
770789
return 0;
771790
}else{
791
+ if(includeLeadingComma){
792
+ CX(",");
793
+ }
772794
zUuid = rid_to_uuid(pWiki->rid);
773795
CX("{\"name\": %!j, \"type\": %!j, "
774796
"\"version\": %!j, "
775797
"\"mimetype\": %!j, ",
776798
pWiki->zWikiTitle,
@@ -853,11 +875,11 @@
853875
}
854876
blob_init(&content, zContent ? zContent : "", -1);
855877
cgi_set_content_type("application/json");
856878
db_begin_transaction();
857879
wiki_cmd_commit(zPageName, parentRid, &content, zMimetype, 0);
858
- rollback = wiki_ajax_emit_page_object(zPageName, 1) ? 0 : 1;
880
+ rollback = wiki_ajax_emit_page_object(zPageName, 1, 0, 0) ? 0 : 1;
859881
db_end_transaction(rollback);
860882
}
861883
862884
/*
863885
** Ajax route handler for /wikiajax/fetch.
@@ -876,11 +898,11 @@
876898
if( zPageName==0 || zPageName[0]==0 ){
877899
ajax_route_error(400,"Missing page name.");
878900
return;
879901
}
880902
cgi_set_content_type("application/json");
881
- wiki_ajax_emit_page_object(zPageName, 1);
903
+ wiki_ajax_emit_page_object(zPageName, 1, 0, 0);
882904
}
883905
884906
/*
885907
** Ajax route handler for /wikiajax/diff.
886908
**
@@ -984,17 +1006,18 @@
9841006
" UNION SELECT 'Sandbox' AS name"
9851007
" ORDER BY name COLLATE NOCASE");
9861008
CX("[");
9871009
while( SQLITE_ROW==db_step(&q) ){
9881010
char const * zName = db_column_text(&q,0);
989
- if(n++){
990
- CX(",");
991
- }
9921011
if(verbose==0){
1012
+ if(n++){
1013
+ CX(",");
1014
+ }
9931015
CX("%!j", zName);
9941016
}else{
995
- wiki_ajax_emit_page_object(zName, includeContent);
1017
+ wiki_ajax_emit_page_object(zName, includeContent,
1018
+ n++>0, 1);
9961019
}
9971020
}
9981021
CX("]");
9991022
db_finalize(&q);
10001023
db_end_transaction(0);
10011024
--- src/wiki.c
+++ src/wiki.c
@@ -725,12 +725,24 @@
725 ** Loads the given wiki page, sets the response type to
726 ** application/json, and emits it as a JSON object. If zPageName is a
727 ** sandbox page then a "fake" object is emitted, as the wikiajax API
728 ** does not permit saving the sandbox.
729 **
730 ** Returns true on success, false on error, and on error it
731 ** queues up a JSON-format error response.
 
 
 
 
 
 
 
 
 
 
 
 
732 **
733 ** Output JSON format:
734 **
735 ** { name: "page name",
736 ** type: "normal" | "tag" | "checkin" | "branch" | "sandbox",
@@ -743,18 +755,23 @@
743 ** }
744 **
745 ** If includeContent is false then the content member is elided.
746 */
747 static int wiki_ajax_emit_page_object(const char *zPageName,
748 int includeContent){
 
 
749 Manifest * pWiki = 0;
750 char * zUuid;
751
752 if( is_sandbox(zPageName) ){
753 char * zMimetype =
754 db_get("sandbox-mimetype","text/x-fossil-wiki");
755 char * zBody = db_get("sandbox","");
 
 
 
756 CX("{\"name\": %!j, \"type\": \"sandbox\", "
757 "\"mimetype\": %!j, \"version\": null, \"parent\": null",
758 zPageName, zMimetype);
759 if(includeContent){
760 CX(", \"content\": %!j",
@@ -763,14 +780,19 @@
763 CX("}");
764 fossil_free(zMimetype);
765 fossil_free(zBody);
766 return 1;
767 }else if( !wiki_fetch_by_name(zPageName, 0, 0, &pWiki) ){
768 ajax_route_error(404, "Wiki page could not be loaded: %s",
769 zPageName);
 
 
770 return 0;
771 }else{
 
 
 
772 zUuid = rid_to_uuid(pWiki->rid);
773 CX("{\"name\": %!j, \"type\": %!j, "
774 "\"version\": %!j, "
775 "\"mimetype\": %!j, ",
776 pWiki->zWikiTitle,
@@ -853,11 +875,11 @@
853 }
854 blob_init(&content, zContent ? zContent : "", -1);
855 cgi_set_content_type("application/json");
856 db_begin_transaction();
857 wiki_cmd_commit(zPageName, parentRid, &content, zMimetype, 0);
858 rollback = wiki_ajax_emit_page_object(zPageName, 1) ? 0 : 1;
859 db_end_transaction(rollback);
860 }
861
862 /*
863 ** Ajax route handler for /wikiajax/fetch.
@@ -876,11 +898,11 @@
876 if( zPageName==0 || zPageName[0]==0 ){
877 ajax_route_error(400,"Missing page name.");
878 return;
879 }
880 cgi_set_content_type("application/json");
881 wiki_ajax_emit_page_object(zPageName, 1);
882 }
883
884 /*
885 ** Ajax route handler for /wikiajax/diff.
886 **
@@ -984,17 +1006,18 @@
984 " UNION SELECT 'Sandbox' AS name"
985 " ORDER BY name COLLATE NOCASE");
986 CX("[");
987 while( SQLITE_ROW==db_step(&q) ){
988 char const * zName = db_column_text(&q,0);
989 if(n++){
990 CX(",");
991 }
992 if(verbose==0){
 
 
 
993 CX("%!j", zName);
994 }else{
995 wiki_ajax_emit_page_object(zName, includeContent);
 
996 }
997 }
998 CX("]");
999 db_finalize(&q);
1000 db_end_transaction(0);
1001
--- src/wiki.c
+++ src/wiki.c
@@ -725,12 +725,24 @@
725 ** Loads the given wiki page, sets the response type to
726 ** application/json, and emits it as a JSON object. If zPageName is a
727 ** sandbox page then a "fake" object is emitted, as the wikiajax API
728 ** does not permit saving the sandbox.
729 **
730 ** If includeLeadingComma is true then a comma will be emitted
731 ** preceeding the object. This parameter is a bit of a hack to allow
732 ** wiki page list generation to recover from an unusual (so far unique
733 ** to one repo) error mode.
734 **
735 ** Returns true on success, false on error. Its behaviour on error
736 ** depends on the 4th argument: if it's true, this function simply
737 ** returns false, else it queues up a JSON response and returns false.
738 ** The intention of this flag is to avoid a weird corner case seen, so
739 ** far, only on the main fossil repo (not clones of it) in which
740 ** loading fails for a page named "Security Desk Technician". The
741 ** hypothesis is that that page was once shunned on the core repo, but
742 ** a reference to it still exists in the tables from which we pull the
743 ** wiki list.
744 **
745 ** Output JSON format:
746 **
747 ** { name: "page name",
748 ** type: "normal" | "tag" | "checkin" | "branch" | "sandbox",
@@ -743,18 +755,23 @@
755 ** }
756 **
757 ** If includeContent is false then the content member is elided.
758 */
759 static int wiki_ajax_emit_page_object(const char *zPageName,
760 int includeContent,
761 int includeLeadingComma,
762 int ignoreLoadError){
763 Manifest * pWiki = 0;
764 char * zUuid;
765
766 if( is_sandbox(zPageName) ){
767 char * zMimetype =
768 db_get("sandbox-mimetype","text/x-fossil-wiki");
769 char * zBody = db_get("sandbox","");
770 if(includeLeadingComma){
771 CX(",");
772 }
773 CX("{\"name\": %!j, \"type\": \"sandbox\", "
774 "\"mimetype\": %!j, \"version\": null, \"parent\": null",
775 zPageName, zMimetype);
776 if(includeContent){
777 CX(", \"content\": %!j",
@@ -763,14 +780,19 @@
780 CX("}");
781 fossil_free(zMimetype);
782 fossil_free(zBody);
783 return 1;
784 }else if( !wiki_fetch_by_name(zPageName, 0, 0, &pWiki) ){
785 if(ignoreLoadError!=0){
786 ajax_route_error(404, "Wiki page could not be loaded: %s",
787 zPageName);
788 }
789 return 0;
790 }else{
791 if(includeLeadingComma){
792 CX(",");
793 }
794 zUuid = rid_to_uuid(pWiki->rid);
795 CX("{\"name\": %!j, \"type\": %!j, "
796 "\"version\": %!j, "
797 "\"mimetype\": %!j, ",
798 pWiki->zWikiTitle,
@@ -853,11 +875,11 @@
875 }
876 blob_init(&content, zContent ? zContent : "", -1);
877 cgi_set_content_type("application/json");
878 db_begin_transaction();
879 wiki_cmd_commit(zPageName, parentRid, &content, zMimetype, 0);
880 rollback = wiki_ajax_emit_page_object(zPageName, 1, 0, 0) ? 0 : 1;
881 db_end_transaction(rollback);
882 }
883
884 /*
885 ** Ajax route handler for /wikiajax/fetch.
@@ -876,11 +898,11 @@
898 if( zPageName==0 || zPageName[0]==0 ){
899 ajax_route_error(400,"Missing page name.");
900 return;
901 }
902 cgi_set_content_type("application/json");
903 wiki_ajax_emit_page_object(zPageName, 1, 0, 0);
904 }
905
906 /*
907 ** Ajax route handler for /wikiajax/diff.
908 **
@@ -984,17 +1006,18 @@
1006 " UNION SELECT 'Sandbox' AS name"
1007 " ORDER BY name COLLATE NOCASE");
1008 CX("[");
1009 while( SQLITE_ROW==db_step(&q) ){
1010 char const * zName = db_column_text(&q,0);
 
 
 
1011 if(verbose==0){
1012 if(n++){
1013 CX(",");
1014 }
1015 CX("%!j", zName);
1016 }else{
1017 wiki_ajax_emit_page_object(zName, includeContent,
1018 n++>0, 1);
1019 }
1020 }
1021 CX("]");
1022 db_finalize(&q);
1023 db_end_transaction(0);
1024
--- www/changes.wiki
+++ www/changes.wiki
@@ -4,12 +4,13 @@
44
<h2>Changes for Version 2.13 (pending)</h2>
55
66
* <i>TBD...</i>
77
88
<a name='v2_12'></a>
9
-<h2>Changes for Version 2.12 (2020-08-16)</h2>
9
+<h2>Changes for Version 2.12.1 (2020-08-20)</h2>
1010
11
+ * (2.12.1): Fix client-side vulnerabilities discovered by Max Justicz.
1112
* Security fix in the "[/help?cmd=git|fossil git export]" command.
1213
The same fix is also backported to version 2.10.1 and 2.11.1.
1314
New "safety-net" features were added to prevent similar problems
1415
in the future.
1516
* Enhancements to the graph display for cases when there are
@@ -85,10 +86,12 @@
8586
* Countless documentation enhancements.
8687
8788
<a name='v2_11'></a>
8889
<h2>Changes for Version 2.11 (2020-05-25)</h2>
8990
91
+ * (2.11.2): Backport security fixes from 2.12.1
92
+ * (2.11.1): Backport security fix for the "fossil git export" command.
9093
* Support [/md_rules|Markdown] in the default ticket configuration.
9194
* Timestamp strings in [./checkin_names.wiki|object names]
9295
can now omit punctation. So, for example, "202004181942" and
9396
"2020-04-18 19:42" mean the same thing.
9497
* Enhance backlink processing so that it works with Markdown-formatted
@@ -174,10 +177,12 @@
174177
* Many minor enhancements to existing features.
175178
176179
<a name='v2_10'></a>
177180
<h2>Changes for Version 2.10 (2019-10-04)</h2>
178181
182
+ * (2.10.2): backport security fixes from 2.12.1
183
+ * (2.10.1): backport security fix for the "fossil git export" command.
179184
* Added support for [./serverext.wiki|CGI-based Server Extensions].
180185
* Added the [/help?cmd=repolist-skin|repolist-skin] setting used to
181186
add style to repository list pages.
182187
* Enhance the hierarchical display of Forum threads to do less
183188
indentation and to provide links back to the previous message
184189
--- www/changes.wiki
+++ www/changes.wiki
@@ -4,12 +4,13 @@
4 <h2>Changes for Version 2.13 (pending)</h2>
5
6 * <i>TBD...</i>
7
8 <a name='v2_12'></a>
9 <h2>Changes for Version 2.12 (2020-08-16)</h2>
10
 
11 * Security fix in the "[/help?cmd=git|fossil git export]" command.
12 The same fix is also backported to version 2.10.1 and 2.11.1.
13 New "safety-net" features were added to prevent similar problems
14 in the future.
15 * Enhancements to the graph display for cases when there are
@@ -85,10 +86,12 @@
85 * Countless documentation enhancements.
86
87 <a name='v2_11'></a>
88 <h2>Changes for Version 2.11 (2020-05-25)</h2>
89
 
 
90 * Support [/md_rules|Markdown] in the default ticket configuration.
91 * Timestamp strings in [./checkin_names.wiki|object names]
92 can now omit punctation. So, for example, "202004181942" and
93 "2020-04-18 19:42" mean the same thing.
94 * Enhance backlink processing so that it works with Markdown-formatted
@@ -174,10 +177,12 @@
174 * Many minor enhancements to existing features.
175
176 <a name='v2_10'></a>
177 <h2>Changes for Version 2.10 (2019-10-04)</h2>
178
 
 
179 * Added support for [./serverext.wiki|CGI-based Server Extensions].
180 * Added the [/help?cmd=repolist-skin|repolist-skin] setting used to
181 add style to repository list pages.
182 * Enhance the hierarchical display of Forum threads to do less
183 indentation and to provide links back to the previous message
184
--- www/changes.wiki
+++ www/changes.wiki
@@ -4,12 +4,13 @@
4 <h2>Changes for Version 2.13 (pending)</h2>
5
6 * <i>TBD...</i>
7
8 <a name='v2_12'></a>
9 <h2>Changes for Version 2.12.1 (2020-08-20)</h2>
10
11 * (2.12.1): Fix client-side vulnerabilities discovered by Max Justicz.
12 * Security fix in the "[/help?cmd=git|fossil git export]" command.
13 The same fix is also backported to version 2.10.1 and 2.11.1.
14 New "safety-net" features were added to prevent similar problems
15 in the future.
16 * Enhancements to the graph display for cases when there are
@@ -85,10 +86,12 @@
86 * Countless documentation enhancements.
87
88 <a name='v2_11'></a>
89 <h2>Changes for Version 2.11 (2020-05-25)</h2>
90
91 * (2.11.2): Backport security fixes from 2.12.1
92 * (2.11.1): Backport security fix for the "fossil git export" command.
93 * Support [/md_rules|Markdown] in the default ticket configuration.
94 * Timestamp strings in [./checkin_names.wiki|object names]
95 can now omit punctation. So, for example, "202004181942" and
96 "2020-04-18 19:42" mean the same thing.
97 * Enhance backlink processing so that it works with Markdown-formatted
@@ -174,10 +177,12 @@
177 * Many minor enhancements to existing features.
178
179 <a name='v2_10'></a>
180 <h2>Changes for Version 2.10 (2019-10-04)</h2>
181
182 * (2.10.2): backport security fixes from 2.12.1
183 * (2.10.1): backport security fix for the "fossil git export" command.
184 * Added support for [./serverext.wiki|CGI-based Server Extensions].
185 * Added the [/help?cmd=repolist-skin|repolist-skin] setting used to
186 add style to repository list pages.
187 * Enhance the hierarchical display of Forum threads to do less
188 indentation and to provide links back to the previous message
189
+1 -1
--- www/index.wiki
+++ www/index.wiki
@@ -84,11 +84,11 @@
8484
the repository are consistent prior to each commit.
8585
8686
8. <b>Free and Open-Source</b> - Uses the [../COPYRIGHT-BSD2.txt|2-clause BSD license].
8787
8888
<hr>
89
-<h3>[/timeline?t=release|Latest Release]: 2.12 (2020-08-16)</h3>
89
+<h3>[https://www.fossil-scm.org/forum/info/a05ae3ce7760daf6|Latest Release]: 2.12.1 (2020-08-20)</h3>
9090
9191
* [/uv/download.html|Download]
9292
* [./changes.wiki#v2_12|Change Summary]
9393
9494
<hr>
9595
--- www/index.wiki
+++ www/index.wiki
@@ -84,11 +84,11 @@
84 the repository are consistent prior to each commit.
85
86 8. <b>Free and Open-Source</b> - Uses the [../COPYRIGHT-BSD2.txt|2-clause BSD license].
87
88 <hr>
89 <h3>[/timeline?t=release|Latest Release]: 2.12 (2020-08-16)</h3>
90
91 * [/uv/download.html|Download]
92 * [./changes.wiki#v2_12|Change Summary]
93
94 <hr>
95
--- www/index.wiki
+++ www/index.wiki
@@ -84,11 +84,11 @@
84 the repository are consistent prior to each commit.
85
86 8. <b>Free and Open-Source</b> - Uses the [../COPYRIGHT-BSD2.txt|2-clause BSD license].
87
88 <hr>
89 <h3>[https://www.fossil-scm.org/forum/info/a05ae3ce7760daf6|Latest Release]: 2.12.1 (2020-08-20)</h3>
90
91 * [/uv/download.html|Download]
92 * [./changes.wiki#v2_12|Change Summary]
93
94 <hr>
95

Keyboard Shortcuts

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