support sandboxed markdown plugins

This commit is contained in:
ed 2023-01-29 00:57:08 +00:00
parent c50cb66aef
commit 2569005139
3 changed files with 39 additions and 17 deletions

View file

@ -6605,7 +6605,7 @@ function show_md(md, name, div, url, depth) {
md_plug = {}
md = load_md_plug(md, 'pre');
md = load_md_plug(md, 'post');
md = load_md_plug(md, 'post', sb_md);
var marked_opts = {
headerPrefix: 'md-',
@ -6618,7 +6618,8 @@ function show_md(md, name, div, url, depth) {
try {
clmod(div, 'mdo', 1);
sandbox(div, sb_md, 'mdo', marked.parse(md, marked_opts));
if (sandbox(div, sb_md, 'mdo', marked.parse(md, marked_opts)))
return;
ext = md_plug.post;
ext = ext ? [ext[0].render, ext[0].render2] : [];
@ -6687,13 +6688,20 @@ function sandbox(tgt, rules, cls, html) {
want = hash.slice(1);
html = '<html class="' + document.documentElement.className + '"><head><style>' + globalcss() +
'</style><base target="_parent"></head><body class="logue ' + cls + '">' + html +
'<script>setTimeout(function(){var its=0,pih=-1,f=function(){' +
'var d=document.documentElement,ih=2+Math.min(parseInt(getComputedStyle(d).height),d.scrollHeight);' +
'</style><base target="_parent"></head><body id="b" class="logue ' + cls + '">' + html +
'<script src="' + SR + '/.cpr/util.js?_={{ ts }}"></script>' +
'<script>var ebi=document.getElementById.bind(document),d=document.documentElement,' +
'loc=new URL("' + location.href.split('?')[0] + '");' +
'setTimeout(function(){var its=0,pih=-1,f=function(){' +
'var ih=2+Math.min(parseInt(getComputedStyle(d).height),d.scrollHeight);' +
'if(ih!=pih){pih=ih;window.parent.postMessage("iheight #' + tid + '>iframe "+ih,"*")}' +
'if(++its<20)return setTimeout(f,20);if(its==20)setInterval(f,200)' +
'};f();var el="' + want + '"&&document.getElementById("' + want + '");' +
'if(el)window.parent.postMessage("iscroll #' + tid + ' "+el.offsetTop,"*")' +
'};f();var el="' + want + '"&&ebi("' + want + '");' +
'if(el)window.parent.postMessage("iscroll #' + tid + ' "+el.offsetTop,"*");' +
(cls == 'mdo' && md_plug.post ?
'const x={' + md_plug.post + '};' +
'if(x.render)x.render(ebi("b"));' +
'if(x.render2)x.render2(ebi("b"));' : '') +
'},1)</script></body></html>';
var fr = mknod('iframe');

View file

@ -1532,25 +1532,33 @@ var md_plug_err = function (ex, js) {
if (ex)
console.log(ex, js);
};
function load_md_plug(md_text, plug_type) {
function load_md_plug(md_text, plug_type, defer) {
if (defer)
md_plug[plug_type] = null;
if (!have_emp)
return md_text;
var find = '\n```copyparty_' + plug_type + '\n';
var ofs = md_text.indexOf(find);
if (ofs === -1)
var find = '\n```copyparty_' + plug_type + '\n',
md = md_text.replace(/\r/g, ''),
ofs = md.indexOf(find),
ofs2 = md.indexOf('\n```', ofs + 1);
if (ofs < 0 || ofs2 < 0)
return md_text;
var ofs2 = md_text.indexOf('\n```', ofs + 1);
if (ofs2 == -1)
return md_text;
var js = md.slice(ofs + find.length, ofs2 + 1);
md = md.slice(0, ofs + 1) + md.slice(ofs2 + 4);
md = md.replace(/$/g, '\r');
var js = md_text.slice(ofs + find.length, ofs2 + 1);
var md = md_text.slice(0, ofs + 1) + md_text.slice(ofs2 + 4);
if (defer) { // insert into sandbox
md_plug[plug_type] = js;
return md;
}
var old_plug = md_plug[plug_type];
if (!old_plug || old_plug[1] != js) {
js = 'const x = { ' + js + ' }; x;';
js = 'const loc = new URL("' + location.href + '"), x = { ' + js + ' }; x;';
try {
var x = eval(js);
if (x['ctor']) {

View file

@ -54,6 +54,8 @@ the values in the `ex:` columns are linkified to `example.com/$value`
and the table can be sorted by clicking the headers
the sandbox also makes `location` unavailable but there is `loc` instead; this website's url is <big><big><b id="whereami">foo</b></big></big>
the difference is that with `copyparty_pre` you'll probably break various copyparty features but if you use `copyparty_post` then future copyparty versions will probably break you
@ -136,6 +138,10 @@ render(dom) {
}
},
render2(dom) {
// loc == window.location except available inside sandbox
ebi('whereami').innerHTML = loc.href;
// this one also works because util.js gets pulled into the sandbox
window.makeSortable(dom.getElementsByTagName('table')[0]);
}
```