openvibers/openvibe.watch Commits

The update log's lists are escaped once (#183)

OP OpenVibers committed 11 days ago · 2cc792995c · 2 files, +26 −1

/updates showed its bullet lists as text ("<ul><li>… watch's"): the list was
joined into a plain string, which the page's html`` escaped again. It is raw markup now (each
item is still escaped by html``); test/changelog.test.js keeps it so.

Changes

ddiff --git a/server/render/changelog.js b/server/render/changelog.js
iindex 239976b..da22f24 100644
---- a/server/render/changelog.js
++++ b/server/render/changelog.js
@@@ -25,7 +25,9 @@ const inline = (s) => raw(String(s)
function renderMarkdown(md) {
const out = [];
let list = null;
-- const flush = () => { if (list) { out.push(`<ul>${list.join('')}</ul>`); list = null; } };
++ // The list is markup already (each item escaped by html``): raw, or the page escapes it a second time (/updates showed
++ // "&lt;ul&gt;&lt;li&gt;… watch&amp;#39;s", 2026-11-02).
++ const flush = () => { if (list) { out.push(raw(`<ul>${list.join('')}</ul>`)); list = null; } };
for (const line of String(md).split(/\r?\n/)) {
const t = line.trim();
if (!t) { flush(); continue; }
ddiff --git a/test/changelog.test.js b/test/changelog.test.js
nnew file mode 100644
iindex 0000000..e15e076
---- /dev/null
++++ b/test/changelog.test.js
@@@ -0,0 +1,23 @@
++'use strict';
++/**
++ * The update log (/updates, server/render/changelog.js): a bullet list is markup once, never escaped a second time
++ * (2026-11-02 the page showed "&lt;ul&gt;&lt;li&gt;… watch&amp;#39;s"), and what the changelog says is still escaped.
++ */
++const assert = require('assert');
++const { renderMarkdown } = require('../server/render/changelog');
++
++const out = String(renderMarkdown([
++ '## 2026-11-01 — the condition in words',
++ '',
++ "- The watch's condition in one sentence, with `code` and **bold**.",
++ '- A second item <script>alert(1)</script>',
++ '',
++ 'A paragraph after the list.',
++].join('\n')));
++
++assert.match(out, /<ul><li>The watch&#39;s condition in one sentence, with <code>code<\/code> and <strong>bold<\/strong>\.<\/li><li>/, out);
++assert.ok(!out.includes('&lt;ul&gt;') && !out.includes('&amp;#39;'), `a list is escaped once: ${out}`);
++assert.ok(out.includes('&lt;script&gt;') && !out.includes('<script>'), 'what the changelog says is still text');
++assert.match(out, /<h2>2026-11-01 — the condition in words<\/h2>/);
++assert.match(out, /<p>A paragraph after the list\.<\/p>/);
++console.log('changelog: all checks passed');