Skip to content

Commit

Permalink
Fix HTML escaping
Browse files Browse the repository at this point in the history
  • Loading branch information
kazk committed Feb 18, 2022
1 parent 342a266 commit 3ae5cac
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 13 deletions.
29 changes: 16 additions & 13 deletions src/method-doc.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export function methodDoc(code, language, render) {
html.push(methodHeader(json, language));
}
if (json.desc) {
html.push(render(json.desc));
html.push(render(escapeHtml(json.desc)));
}

html.push(`<div class="block block--doc">`);
Expand All @@ -36,11 +36,11 @@ export function methodDoc(code, language, render) {

if (json.constraints && json.constraints.length) {
html.push(`<dt>Constraints</dt>`);
html.push(json.constraints.map(markdownDefD(render)).join('\n'));
html.push(json.constraints.map(escapeHtml).map(markdownDefD(render)).join('\n'));
}
if (json.errors && json.errors.length) {
html.push(`<dt>Errors</dt>`);
html.push(json.errors.map(markdownDefD(render)).join('\n'));
html.push(json.errors.map(escapeHtml).map(markdownDefD(render)).join('\n'));
}

html.push(`</dl>`);
Expand Down Expand Up @@ -81,22 +81,22 @@ function exampleRows(json) {
function exampleRow(example, hasExamples) {
const tds = [];
if (hasExamples) {
tds.push(`<em>${example.name || 'Example'}</em>`);
tds.push(`<em>${escapeHtml(example.name || 'Example')}</em>`);
}
if (example.args) tds.push(...example.args.map(formatExampleValue));
tds.push(formatExampleValue(example.returns) || '');
return tds.map((t) => `<td>${t}</td>`).join('');
}

function formatExampleValue(value) {
return `<code>${JSON.stringify(value)}</code>`;
return `<code>${escapeHtml(JSON.stringify(value))}</code>`;
}

function exampleHeader(json) {
const keys = hasExampleNames(json) ? [''] : [];
keys.push(...Object.keys(getArgs(json)));
keys.push('Return Value');
return `<tr>${keys.map((k) => `<th>${k}</th>`).join('')}</tr>`;
return `<tr>${keys.map((k) => `<th>${escapeHtml(k)}</th>`).join('')}</tr>`;
}

function getArgs(json) {
Expand All @@ -106,15 +106,17 @@ function getArgs(json) {
function methodName(json, language) {
// if a class is provided, it will always be shown and overrides global
const prefix = json.class
? docClass(json.class, language)
? docClass(escapeHtml(json.class), language)
: json.global !== false
? docGlobal(json.global || 'Challenge', language)
? docGlobal(escapeHtml(json.global || 'Challenge'), language)
: '';
return `${prefix}${prefix ? '.' : ''}${docMethod(json.method, language)}`;
return `${prefix}${prefix ? '.' : ''}${docMethod(escapeHtml(json.method), language)}`;
}

function methodHeader(json, language) {
const args = Object.keys(getArgs(json)).map((key) => `<code>${docName(key, language)}</code>`);
const args = Object.keys(getArgs(json)).map(
(key) => `<code>${docName(escapeHtml(key), language)}</code>`
);
return `<h3><code>${methodName(json, language)}</code>(${args.join(', ')})</h3>`;
}

Expand All @@ -123,16 +125,17 @@ function parameters(json, language) {
return Object.keys(args).map((key) => {
const arg = args[key];
const type = typeof arg === 'string' ? arg : arg.type;
const md = `${docName(key, language)}: ${formatDocType(json, type, 'String', language)}`;
return md + (arg.desc ? ` - ${arg.desc}` : '');
const name = docName(escapeHtml(key), language);
const md = `${name}: ${formatDocType(json, type, 'String', language)}`;
return md + (arg.desc ? ` - ${escapeHtml(arg.desc)}` : '');
});
}

function returnType(json, language) {
if (json.returns) {
const type = typeof json.returns === 'string' ? json.returns : json.returns.type;
const md = formatDocType(json, type, 'void', language);
return md + (json.returns.desc ? ` - ${json.returns.desc}` : '');
return md + (json.returns.desc ? ` - ${escapeHtml(json.returns.desc)}` : '');
}
return docType('void', language);
}
Expand Down
165 changes: 165 additions & 0 deletions test/__snapshots__/method-doc.spec.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,170 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`%method-doc escape html should match snapshot 1`] = `
<h1 id="documentation">
Documentation
</h1>
<p>
This is some text
</p>
<div class="block block--docs method-doc">
<h3>
<code>
<dfn class="doc-name doc-name--method">
&lt;open_files&gt;
</dfn>
</code>
(
<code>
<dfn class="doc-name doc-name--name">
files
</dfn>
</code>
,
<code>
<dfn class="doc-name doc-name--name">
ext&lt;a&gt;
</dfn>
</code>
)
</h3>
<p>
Loops through any files that are not opened and opens them &lt;a&gt;
</p>
<div class="block block--doc">
<dl>
<dt>
Parameters
</dt>
<dd>
<p>
<dfn class="doc-name doc-name--name">
files
</dfn>
:
<dfn class="doc-type">
Array&lt;File&gt;
</dfn>
- An array of file &lt;objects&gt; that may need to be opened
</p>
</dd>
<dd>
<p>
<dfn class="doc-name doc-name--name">
ext&lt;a&gt;
</dfn>
:
<dfn class="doc-type">
&lt;String&gt;
</dfn>
- An optional extension that may be used as a filter to &lt;determine&gt; which files to open
</p>
</dd>
<dt>
Return Value
</dt>
<dd>
<p>
<dfn class="doc-type">
Array&lt;File&gt;
</dfn>
- &lt;A&gt; filtered array of files that were opened
</p>
</dd>
<dt>
Constraints
</dt>
<dd>
<p>
0 &lt;= files.length &lt;= 10 &lt;a&gt;
</p>
</dd>
<dt>
Errors
</dt>
<dd>
<p>
&lt;a&gt; error
</p>
</dd>
<dd>
<p>
foo
</p>
</dd>
</dl>
</div>
<div class="block block--doc-block">
<h4>
Examples
</h4>
<table>
<thead>
<tr>
<th>
</th>
<th>
files
</th>
<th>
ext&lt;a&gt;
</th>
<th>
Return Value
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<em>
Example &lt;A&gt;
</em>
</td>
<td>
<code>
[1,2,3]
</code>
</td>
<td>
<code>
"&lt;js&gt;"
</code>
</td>
<td>
<code>
[1,2,"&lt;a&gt;"]
</code>
</td>
</tr>
<tr>
<td>
<em>
Example
</em>
</td>
<td>
<code>
[1,2,3]
</code>
</td>
<td>
<code>
"rb"
</code>
</td>
<td>
<code>
[3]
</code>
</td>
</tr>
</tbody>
</table>
</div>
</div>
`;

exports[`%method-doc should match snapshot 1`] = `
<h1 id="documentation">
Documentation
Expand Down
41 changes: 41 additions & 0 deletions test/fixtures/method-doc-html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Documentation
This is some text

```%method-doc
{
"method": "<open_files>",
"desc": "Loops through any files that are not opened and opens them <a>",
"args": {
"files": {
"type": "Array<File>",
"desc": "An array of file <objects> that may need to be opened"
},
"ext<a>": {
"type": "<String>",
"desc": "An optional extension that may be used as a filter to <determine> which files to open"
}
},
"constraints": [
"0 <= files.length <= 10 <a>"
],
"errors": [
"<a> error",
"foo"
],
"returns": {
"type": "Array<File>",
"desc": "<A> filtered array of files that were opened"
},
"examples": [
{
"name": "Example <A>",
"args": [[1,2,3], "<js>"],
"returns": [1,2, "<a>"]
},
{
"args": [[1,2,3], "rb"],
"returns": [3]
}
]
}
```
7 changes: 7 additions & 0 deletions test/method-doc.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,10 @@ describe('%method-doc', () => {
expect(example).toMatchSnapshot();
});
});

describe('%method-doc escape html', () => {
it('should match snapshot', () => {
const example = process(marked, fixture('method-doc-html')).html();
expect(example).toMatchSnapshot();
});
});

0 comments on commit 3ae5cac

Please sign in to comment.