Fossil SCM
Merge the latest changes from trunk into sec2020.
Commit
1d61aae3143a4c09262f73f873b95864d40239e07074007a8021abc0910a6cd5
Parent
c93cb2bae950484…
14 files changed
+5
-2
+1
-1
+1
-1
+1
-1
+1
-1
+2
-2
+1
-1
+2
-2
+2
-2
+1
-1
+5
-3
+34
-11
+6
-1
+1
-1
~
auto.def
~
src/copybtn.js
~
src/default.css
~
src/fossil.dom.js
~
src/fossil.numbered-lines.js
~
src/fossil.page.fileedit.js
~
src/fossil.page.forumpost.js
~
src/fossil.page.wikiedit.js
~
src/fossil.popupwidget.js
~
src/fossil.storage.js
~
src/info.c
~
src/wiki.c
~
www/changes.wiki
~
www/index.wiki
M
auto.def
+5
-2
| --- auto.def | ||
| +++ auto.def | ||
| @@ -176,12 +176,15 @@ | ||
| 176 | 176 | } |
| 177 | 177 | if {!$ok} { |
| 178 | 178 | user-error "unable to compile SQLite compatibility test program" |
| 179 | 179 | } |
| 180 | 180 | 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 | + } | |
| 183 | 186 | } |
| 184 | 187 | file delete ./conftest__ |
| 185 | 188 | } |
| 186 | 189 | test_system_sqlite |
| 187 | 190 | |
| 188 | 191 |
| --- 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 @@ | ||
| 80 | 80 | }.bind(null,this.id),400); |
| 81 | 81 | } |
| 82 | 82 | /* Create a temporary <textarea> element and copy the contents to clipboard. */ |
| 83 | 83 | function copyTextToClipboard(text){ |
| 84 | 84 | if( window.clipboardData && window.clipboardData.setData ){ |
| 85 | - clipboardData.setData('Text',text); | |
| 85 | + window.clipboardData.setData('Text',text); | |
| 86 | 86 | }else{ |
| 87 | 87 | var x = document.createElement("textarea"); |
| 88 | 88 | x.style.position = 'fixed'; |
| 89 | 89 | x.value = text; |
| 90 | 90 | document.body.appendChild(x); |
| 91 | 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 | 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 @@ | ||
| 1250 | 1250 | padding: 0.2em 1em; |
| 1251 | 1251 | border: 1px solid black; |
| 1252 | 1252 | border-radius: 0.25em; |
| 1253 | 1253 | position: absolute; |
| 1254 | 1254 | display: inline-block; |
| 1255 | - z-index: 100; | |
| 1255 | + z-index: 19/*below default skin's hamburger popup*/; | |
| 1256 | 1256 | box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.75); |
| 1257 | 1257 | background-color: inherit; |
| 1258 | 1258 | } |
| 1259 | 1259 | |
| 1260 | 1260 | .fossil-toast-message { |
| 1261 | 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: 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 |
+1
-1
| --- src/fossil.dom.js | ||
| +++ src/fossil.dom.js | ||
| @@ -521,11 +521,11 @@ | ||
| 521 | 521 | Attempts to copy the given text to the system clipboard. Returns |
| 522 | 522 | true if it succeeds, else false. |
| 523 | 523 | */ |
| 524 | 524 | dom.copyTextToClipboard = function(text){ |
| 525 | 525 | if( window.clipboardData && window.clipboardData.setData ){ |
| 526 | - clipboardData.setData('Text',text); | |
| 526 | + window.clipboardData.setData('Text',text); | |
| 527 | 527 | return true; |
| 528 | 528 | }else{ |
| 529 | 529 | const x = document.createElement("textarea"); |
| 530 | 530 | x.style.position = 'fixed'; |
| 531 | 531 | x.value = text; |
| 532 | 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 | 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 |
+1
-1
| --- src/fossil.numbered-lines.js | ||
| +++ src/fossil.numbered-lines.js | ||
| @@ -25,11 +25,11 @@ | ||
| 25 | 25 | .replace(/&?\bln=[^&]*/,'') /* inbound line number/range */ |
| 26 | 26 | .replace('?&','?'), |
| 27 | 27 | start: 0, end: 0 |
| 28 | 28 | }; |
| 29 | 29 | |
| 30 | - const lineTip = new fossil.PopupWidget({ | |
| 30 | + const lineTip = new F.PopupWidget({ | |
| 31 | 31 | style: { |
| 32 | 32 | cursor: 'pointer' |
| 33 | 33 | }, |
| 34 | 34 | refresh: function(){ |
| 35 | 35 | const link = this.state.link; |
| 36 | 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 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 |
+2
-2
| --- src/fossil.page.fileedit.js | ||
| +++ src/fossil.page.fileedit.js | ||
| @@ -638,11 +638,11 @@ | ||
| 638 | 638 | }; |
| 639 | 639 | |
| 640 | 640 | F.onPageLoad(function() { |
| 641 | 641 | P.base = {tag: E('base')}; |
| 642 | 642 | P.base.originalHref = P.base.tag.href; |
| 643 | - P.tabs = new fossil.TabManager('#fileedit-tabs'); | |
| 643 | + P.tabs = new F.TabManager('#fileedit-tabs'); | |
| 644 | 644 | P.e = { /* various DOM elements we work with... */ |
| 645 | 645 | taEditor: E('#fileedit-content-editor'), |
| 646 | 646 | taCommentSmall: E('#fileedit-comment'), |
| 647 | 647 | taCommentBig: E('#fileedit-comment-big'), |
| 648 | 648 | taComment: undefined/*gets set to one of taComment{Big,Small}*/, |
| @@ -1142,11 +1142,11 @@ | ||
| 1142 | 1142 | mimetype: P.finfo.mimetype, |
| 1143 | 1143 | element: P.e.previewTarget |
| 1144 | 1144 | }); |
| 1145 | 1145 | }, |
| 1146 | 1146 | onerror: (e)=>{ |
| 1147 | - fossil.fetch.onerror(e); | |
| 1147 | + F.fetch.onerror(e); | |
| 1148 | 1148 | callback("Error fetching preview: "+e); |
| 1149 | 1149 | } |
| 1150 | 1150 | }); |
| 1151 | 1151 | return this; |
| 1152 | 1152 | }; |
| 1153 | 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 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 |
+1
-1
| --- src/fossil.page.forumpost.js | ||
| +++ src/fossil.page.forumpost.js | ||
| @@ -1,9 +1,9 @@ | ||
| 1 | 1 | (function(F/*the fossil object*/){ |
| 2 | 2 | "use strict"; |
| 3 | 3 | /* 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; | |
| 5 | 5 | |
| 6 | 6 | F.onPageLoad(function(){ |
| 7 | 7 | const scrollbarIsVisible = (e)=>e.scrollHeight > e.clientHeight; |
| 8 | 8 | /* Returns an event handler which implements the post expand/collapse toggle |
| 9 | 9 | on contentElem when the given widget is activated. */ |
| 10 | 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 = 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 |
+2
-2
| --- src/fossil.page.wikiedit.js | ||
| +++ src/fossil.page.wikiedit.js | ||
| @@ -855,11 +855,11 @@ | ||
| 855 | 855 | diff: E('#wikiedit-tab-diff'), |
| 856 | 856 | misc: E('#wikiedit-tab-misc') |
| 857 | 857 | //commit: E('#wikiedit-tab-commit') |
| 858 | 858 | } |
| 859 | 859 | }; |
| 860 | - P.tabs = new fossil.TabManager(D.clearElement(P.e.tabContainer)); | |
| 860 | + P.tabs = new F.TabManager(D.clearElement(P.e.tabContainer)); | |
| 861 | 861 | P.tabs.e.container.insertBefore( |
| 862 | 862 | /* Move the status bar between the tab buttons and |
| 863 | 863 | tab panels. Seems to be the best fit in terms of |
| 864 | 864 | functionality and visibility. */ |
| 865 | 865 | E('#fossil-status-bar'), P.tabs.e.tabs |
| @@ -1322,11 +1322,11 @@ | ||
| 1322 | 1322 | mimetype: mimetype, |
| 1323 | 1323 | element: P.e.previewTarget |
| 1324 | 1324 | }); |
| 1325 | 1325 | }, |
| 1326 | 1326 | onerror: (e)=>{ |
| 1327 | - fossil.fetch.onerror(e); | |
| 1327 | + F.fetch.onerror(e); | |
| 1328 | 1328 | callback("Error fetching preview: "+e); |
| 1329 | 1329 | } |
| 1330 | 1330 | }); |
| 1331 | 1331 | return this; |
| 1332 | 1332 | }; |
| 1333 | 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 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 |
+2
-2
| --- src/fossil.popupwidget.js | ||
| +++ src/fossil.popupwidget.js | ||
| @@ -176,12 +176,12 @@ | ||
| 176 | 176 | this.e.style.top = y+"px"; |
| 177 | 177 | } |
| 178 | 178 | D.removeClass(this.e, 'hidden'); |
| 179 | 179 | }else{ |
| 180 | 180 | 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'); | |
| 183 | 183 | } |
| 184 | 184 | return this; |
| 185 | 185 | }, |
| 186 | 186 | |
| 187 | 187 | hide: function(){return this.show(false)} |
| 188 | 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 | 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 |
+1
-1
| --- src/fossil.storage.js | ||
| +++ src/fossil.storage.js | ||
| @@ -89,11 +89,11 @@ | ||
| 89 | 89 | page-instance-local proxy, if neither one is availble. |
| 90 | 90 | |
| 91 | 91 | Which exact storage implementation is uses is unspecified, and |
| 92 | 92 | apps must not rely on it. |
| 93 | 93 | */ |
| 94 | - fossil.storage = { | |
| 94 | + F.storage = { | |
| 95 | 95 | storageKeyPrefix: storageKeyPrefix, |
| 96 | 96 | /** Sets the storage key k to value v, implicitly converting |
| 97 | 97 | it to a string. */ |
| 98 | 98 | set: (k,v)=>$storage.setItem(storageKeyPrefix+k,v), |
| 99 | 99 | /** Sets storage key k to JSON.stringify(v). */ |
| 100 | 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 | 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 @@ | ||
| 2306 | 2306 | const char *zPath; |
| 2307 | 2307 | Blob path; |
| 2308 | 2308 | blob_zero(&path); |
| 2309 | 2309 | hyperlinked_path(zName, &path, zCI, "dir", "", LINKPATH_FINFO); |
| 2310 | 2310 | 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); | |
| 2312 | 2314 | if( isBranchCI ){ |
| 2313 | 2315 | @ on branch %z(href("%R/timeline?r=%T",zCI))%h(zCI)</a></h2> |
| 2314 | 2316 | }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> | |
| 2316 | 2318 | }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> | |
| 2318 | 2320 | } |
| 2319 | 2321 | blob_reset(&path); |
| 2320 | 2322 | } |
| 2321 | 2323 | style_submenu_element("Artifact", "%R/artifact/%S", zUuid); |
| 2322 | 2324 | style_submenu_element("Annotate", "%R/annotate?filename=%T&checkin=%T", |
| 2323 | 2325 |
| --- 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 @@ | ||
| 725 | 725 | ** Loads the given wiki page, sets the response type to |
| 726 | 726 | ** application/json, and emits it as a JSON object. If zPageName is a |
| 727 | 727 | ** sandbox page then a "fake" object is emitted, as the wikiajax API |
| 728 | 728 | ** does not permit saving the sandbox. |
| 729 | 729 | ** |
| 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. | |
| 732 | 744 | ** |
| 733 | 745 | ** Output JSON format: |
| 734 | 746 | ** |
| 735 | 747 | ** { name: "page name", |
| 736 | 748 | ** type: "normal" | "tag" | "checkin" | "branch" | "sandbox", |
| @@ -743,18 +755,23 @@ | ||
| 743 | 755 | ** } |
| 744 | 756 | ** |
| 745 | 757 | ** If includeContent is false then the content member is elided. |
| 746 | 758 | */ |
| 747 | 759 | static int wiki_ajax_emit_page_object(const char *zPageName, |
| 748 | - int includeContent){ | |
| 760 | + int includeContent, | |
| 761 | + int includeLeadingComma, | |
| 762 | + int ignoreLoadError){ | |
| 749 | 763 | Manifest * pWiki = 0; |
| 750 | 764 | char * zUuid; |
| 751 | 765 | |
| 752 | 766 | if( is_sandbox(zPageName) ){ |
| 753 | 767 | char * zMimetype = |
| 754 | 768 | db_get("sandbox-mimetype","text/x-fossil-wiki"); |
| 755 | 769 | char * zBody = db_get("sandbox",""); |
| 770 | + if(includeLeadingComma){ | |
| 771 | + CX(","); | |
| 772 | + } | |
| 756 | 773 | CX("{\"name\": %!j, \"type\": \"sandbox\", " |
| 757 | 774 | "\"mimetype\": %!j, \"version\": null, \"parent\": null", |
| 758 | 775 | zPageName, zMimetype); |
| 759 | 776 | if(includeContent){ |
| 760 | 777 | CX(", \"content\": %!j", |
| @@ -763,14 +780,19 @@ | ||
| 763 | 780 | CX("}"); |
| 764 | 781 | fossil_free(zMimetype); |
| 765 | 782 | fossil_free(zBody); |
| 766 | 783 | return 1; |
| 767 | 784 | }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 | + } | |
| 770 | 789 | return 0; |
| 771 | 790 | }else{ |
| 791 | + if(includeLeadingComma){ | |
| 792 | + CX(","); | |
| 793 | + } | |
| 772 | 794 | zUuid = rid_to_uuid(pWiki->rid); |
| 773 | 795 | CX("{\"name\": %!j, \"type\": %!j, " |
| 774 | 796 | "\"version\": %!j, " |
| 775 | 797 | "\"mimetype\": %!j, ", |
| 776 | 798 | pWiki->zWikiTitle, |
| @@ -853,11 +875,11 @@ | ||
| 853 | 875 | } |
| 854 | 876 | blob_init(&content, zContent ? zContent : "", -1); |
| 855 | 877 | cgi_set_content_type("application/json"); |
| 856 | 878 | db_begin_transaction(); |
| 857 | 879 | 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; | |
| 859 | 881 | db_end_transaction(rollback); |
| 860 | 882 | } |
| 861 | 883 | |
| 862 | 884 | /* |
| 863 | 885 | ** Ajax route handler for /wikiajax/fetch. |
| @@ -876,11 +898,11 @@ | ||
| 876 | 898 | if( zPageName==0 || zPageName[0]==0 ){ |
| 877 | 899 | ajax_route_error(400,"Missing page name."); |
| 878 | 900 | return; |
| 879 | 901 | } |
| 880 | 902 | cgi_set_content_type("application/json"); |
| 881 | - wiki_ajax_emit_page_object(zPageName, 1); | |
| 903 | + wiki_ajax_emit_page_object(zPageName, 1, 0, 0); | |
| 882 | 904 | } |
| 883 | 905 | |
| 884 | 906 | /* |
| 885 | 907 | ** Ajax route handler for /wikiajax/diff. |
| 886 | 908 | ** |
| @@ -984,17 +1006,18 @@ | ||
| 984 | 1006 | " UNION SELECT 'Sandbox' AS name" |
| 985 | 1007 | " ORDER BY name COLLATE NOCASE"); |
| 986 | 1008 | CX("["); |
| 987 | 1009 | while( SQLITE_ROW==db_step(&q) ){ |
| 988 | 1010 | char const * zName = db_column_text(&q,0); |
| 989 | - if(n++){ | |
| 990 | - CX(","); | |
| 991 | - } | |
| 992 | 1011 | if(verbose==0){ |
| 1012 | + if(n++){ | |
| 1013 | + CX(","); | |
| 1014 | + } | |
| 993 | 1015 | CX("%!j", zName); |
| 994 | 1016 | }else{ |
| 995 | - wiki_ajax_emit_page_object(zName, includeContent); | |
| 1017 | + wiki_ajax_emit_page_object(zName, includeContent, | |
| 1018 | + n++>0, 1); | |
| 996 | 1019 | } |
| 997 | 1020 | } |
| 998 | 1021 | CX("]"); |
| 999 | 1022 | db_finalize(&q); |
| 1000 | 1023 | db_end_transaction(0); |
| 1001 | 1024 |
| --- 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 |
+6
-1
| --- www/changes.wiki | ||
| +++ www/changes.wiki | ||
| @@ -4,12 +4,13 @@ | ||
| 4 | 4 | <h2>Changes for Version 2.13 (pending)</h2> |
| 5 | 5 | |
| 6 | 6 | * <i>TBD...</i> |
| 7 | 7 | |
| 8 | 8 | <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> | |
| 10 | 10 | |
| 11 | + * (2.12.1): Fix client-side vulnerabilities discovered by Max Justicz. | |
| 11 | 12 | * Security fix in the "[/help?cmd=git|fossil git export]" command. |
| 12 | 13 | The same fix is also backported to version 2.10.1 and 2.11.1. |
| 13 | 14 | New "safety-net" features were added to prevent similar problems |
| 14 | 15 | in the future. |
| 15 | 16 | * Enhancements to the graph display for cases when there are |
| @@ -85,10 +86,12 @@ | ||
| 85 | 86 | * Countless documentation enhancements. |
| 86 | 87 | |
| 87 | 88 | <a name='v2_11'></a> |
| 88 | 89 | <h2>Changes for Version 2.11 (2020-05-25)</h2> |
| 89 | 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. | |
| 90 | 93 | * Support [/md_rules|Markdown] in the default ticket configuration. |
| 91 | 94 | * Timestamp strings in [./checkin_names.wiki|object names] |
| 92 | 95 | can now omit punctation. So, for example, "202004181942" and |
| 93 | 96 | "2020-04-18 19:42" mean the same thing. |
| 94 | 97 | * Enhance backlink processing so that it works with Markdown-formatted |
| @@ -174,10 +177,12 @@ | ||
| 174 | 177 | * Many minor enhancements to existing features. |
| 175 | 178 | |
| 176 | 179 | <a name='v2_10'></a> |
| 177 | 180 | <h2>Changes for Version 2.10 (2019-10-04)</h2> |
| 178 | 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. | |
| 179 | 184 | * Added support for [./serverext.wiki|CGI-based Server Extensions]. |
| 180 | 185 | * Added the [/help?cmd=repolist-skin|repolist-skin] setting used to |
| 181 | 186 | add style to repository list pages. |
| 182 | 187 | * Enhance the hierarchical display of Forum threads to do less |
| 183 | 188 | indentation and to provide links back to the previous message |
| 184 | 189 |
| --- 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 @@ | ||
| 84 | 84 | the repository are consistent prior to each commit. |
| 85 | 85 | |
| 86 | 86 | 8. <b>Free and Open-Source</b> - Uses the [../COPYRIGHT-BSD2.txt|2-clause BSD license]. |
| 87 | 87 | |
| 88 | 88 | <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> | |
| 90 | 90 | |
| 91 | 91 | * [/uv/download.html|Download] |
| 92 | 92 | * [./changes.wiki#v2_12|Change Summary] |
| 93 | 93 | |
| 94 | 94 | <hr> |
| 95 | 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>[/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 |