Skip to content

Commit

Permalink
in directory listings, properly encode unsafe URL characters in links
Browse files Browse the repository at this point in the history
fixes:
* upstream issue 566
    vercel/serve#566
  • Loading branch information
warren-bank committed Dec 22, 2021
1 parent 829c1d3 commit 2f90d39
Showing 1 changed file with 22 additions and 9 deletions.
31 changes: 22 additions & 9 deletions lib/serve-handler/src/directory.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,22 +192,35 @@ const staticTemplateStrings = {
const doNotSkipEncoded = false
const matchHTML = doNotSkipEncoded ? /[&<>"'\/]/g : /&(?!#?\w+;)|[<>"'\/]/g
const encodeHTMLRules = {
//"/": "&#47;",
"&": "&#38;",
"<": "&#60;",
">": "&#62;",
'"': "&#34;",
"'": "&#39;"
"'": "&#39;",
"/": "&#47;"
}

const encodeHTML = code => {
return (!code || (typeof code !== 'string'))
const matchURL = /[ <>%#\?]/g
const encodeURLRules = {
" ": "%20",
"<": "%3C",
">": "%3E",
'%': "%25",
"#": "%23",
"?": "%3F"
}

const encodeString = (text, charset_regex, charset_map) => {
return (!text || (typeof text !== 'string'))
? ''
: code.toString().replace(matchHTML, function(m) {
return encodeHTMLRules[m] || m
: text.toString().replace(charset_regex, function(char_value) {
return charset_map[char_value] || char_value
})
}

const encodeHTML = text => encodeString(text, matchHTML, encodeHTMLRules)
const encodeURL = text => encodeString(text, matchURL, encodeURLRules)

const directoryTemplate = spec => {
const {paths, files} = spec
const title = encodeHTML(spec.directory)
Expand All @@ -220,7 +233,7 @@ const directoryTemplate = spec => {

if (Array.isArray(paths) && paths.length) {
for (let path of paths) {
html += `<a href="/${encodeHTML(path.url)}">${encodeHTML(path.name)}</a>`
html += `<a href="/${encodeURL(path.url)}">${encodeHTML(path.name)}</a>`
}
}

Expand All @@ -230,10 +243,10 @@ const directoryTemplate = spec => {
if (Array.isArray(files) && files.length) {
for (let file of files) {
html += '<li>'
html += `<a href="${encodeHTML(file.relative)}" title="${encodeHTML(file.title)}" class="${encodeHTML(file.type)} ${encodeHTML(file.ext)}">${encodeHTML(file.base)}</a>`
html += `<a href="${encodeURL(file.relative)}" title="${encodeHTML(file.title)}" class="${encodeHTML(file.type)} ${encodeHTML(file.ext)}">${encodeHTML(file.base)}</a>`

if ((file.stats instanceof Object) && file.stats.mtime)
html += `<div class="file-stats">${file.stats.size ? `${file.stats.size} | ` : ''}${file.stats.mtime}</div>`
html += `<div class="file-stats">${file.stats.size ? `${encodeHTML(file.stats.size)} | ` : ''}${encodeHTML(file.stats.mtime)}</div>`

html += '</li>'
}
Expand Down

0 comments on commit 2f90d39

Please sign in to comment.