fix: special characters in album titles

This commit is contained in:
Bobby 2023-12-06 05:55:50 +07:00
parent 29eb1c9550
commit d49c337dad
No known key found for this signature in database
GPG Key ID: B2F45B6A3C9A8FCA
7 changed files with 33 additions and 56 deletions

View File

@ -452,7 +452,7 @@ self.edit = async (req, res) => {
identifier: update.identifier identifier: update.identifier
}) })
} else { } else {
return res.json({ success: true, name }) return res.json({ success: true, name: utils.unescape(name) })
} }
} }

View File

@ -54,7 +54,8 @@ class NunjucksRenderer {
resolve(html) resolve(html)
}) })
}).then(html => { }).then(html => {
res.type('html').send(html) res.header('Content-Type', 'text/html; charset=utf-8')
res.send(html)
return html return html
}) })
} }

View File

@ -292,56 +292,30 @@ self.extname = (filename, lower) => {
return lower ? str.toLowerCase() : str return lower ? str.toLowerCase() : str
} }
const escapeMap = {
'&': '&',
'"': '"',
'\'': ''',
'<': '&lt;',
'>': '&gt;',
'\\': '&#92;'
}
const escapeRegex = /[&"'<>\\]/g
const unescapeMap = Object.keys(escapeMap).reduce((ret, key) => {
ret[escapeMap[key]] = key
return ret
}, {})
const unescapeRegex = /&(amp|quot|#39|lt|gt|#92);/g
self.escape = string => { self.escape = string => {
// MIT License return string.replace(escapeRegex, key => escapeMap[key])
// Copyright(c) 2012-2013 TJ Holowaychuk }
// Copyright(c) 2015 Andreas Lubbe
// Copyright(c) 2015 Tiancheng "Timothy" Gu
if (!string) return string self.unescape = string => {
return string.replace(unescapeRegex, key => unescapeMap[key])
const str = String(string)
const match = /["'&<>]/.exec(str)
if (!match) return str
let escape
let html = ''
let index = 0
let lastIndex = 0
for (index = match.index; index < str.length; index++) {
switch (str.charCodeAt(index)) {
case 34: // "
escape = '&quot;'
break
case 38: // &
escape = '&amp;'
break
case 39: // '
escape = '&#39;'
break
case 60: // <
escape = '&lt;'
break
case 62: // >
escape = '&gt;'
break
default:
continue
}
if (lastIndex !== index) {
html += str.substring(lastIndex, index)
}
lastIndex = index + 1
html += escape
}
return lastIndex !== index
? html + str.substring(lastIndex, index)
: html
} }
self.stripIndents = string => { self.stripIndents = string => {

View File

@ -23,6 +23,7 @@ routes.get('/a/:identifier', async (req, res) => {
return errors.handleNotFound(req, res) return errors.handleNotFound(req, res)
} }
album.name = utils.unescape(album.name)
const nojs = req.query_parameters.nojs !== undefined const nojs = req.query_parameters.nojs !== undefined
let cacheid let cacheid
@ -32,7 +33,8 @@ routes.get('/a/:identifier', async (req, res) => {
const cache = utils.albumRenderStore.get(cacheid) const cache = utils.albumRenderStore.get(cacheid)
if (cache) { if (cache) {
return res.type('html').send(cache) res.header('Content-Type', 'text/html; charset=utf-8')
return res.send(cache)
} else if (cache === null) { } else if (cache === null) {
return res.render('album-notice', { return res.render('album-notice', {
config, config,

View File

@ -22,7 +22,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>{{ title }}</title> <title>{{ title | safe }}</title>
{% block stylesheets %} {% block stylesheets %}
<!-- Stylesheets --> <!-- Stylesheets -->
@ -33,7 +33,7 @@
<!-- Open Graph tags --> <!-- Open Graph tags -->
<meta property="og:url" content="{{ url }}" /> <meta property="og:url" content="{{ url }}" />
<meta property="og:type" content="website" /> <meta property="og:type" content="website" />
<meta property="og:title" content="{{ title }}" /> <meta property="og:title" content="{{ title | safe }}" />
<meta property="og:description" content="{{ metaDesc or globals.description }}" /> <meta property="og:description" content="{{ metaDesc or globals.description }}" />
{%- if metaImage %} {%- if metaImage %}
<meta property="og:image" content="{{ metaImage }}" /> <meta property="og:image" content="{{ metaImage }}" />
@ -48,7 +48,7 @@
<!-- Twitter Card tags --> <!-- Twitter Card tags -->
<meta name="twitter:card" content="summary_large_image"> <meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ title }}"> <meta name="twitter:title" content="{{ title | safe }}">
<meta name="twitter:description" content="{{ metaDesc or globals.description }}"> <meta name="twitter:description" content="{{ metaDesc or globals.description }}">
{%- if metaImage %} {%- if metaImage %}
<meta name="twitter:image" content="{{ metaImage }}"> <meta name="twitter:image" content="{{ metaImage }}">

View File

@ -1,5 +1,5 @@
{% set metaTitle %} {% set metaTitle %}
{{- album.name | truncate(60, true, '…') -}} {{- album.name | safe | truncate(60, true, '…') -}}
{% endset %} {% endset %}
{% set metaDesc = album.description | striptags | truncate(200, true, '…') %} {% set metaDesc = album.description | striptags | truncate(200, true, '…') %}
{% set metaUrl = '/' + album.url %} {% set metaUrl = '/' + album.url %}

View File

@ -1,5 +1,5 @@
{% set metaTitle %} {% set metaTitle %}
{{- album.name | truncate(60, true, '…') + ' ' + files.length + ' file' + ('s' if files.length !== 1) -}} {{- album.name | safe | truncate(60, true, '…') }} - {{ files.length + ' file' + ('s' if files.length !== 1) -}}
{% endset %} {% endset %}
{% set metaDesc = album.description | striptags | truncate(200, true, '…') %} {% set metaDesc = album.description | striptags | truncate(200, true, '…') %}
{% set metaUrl = '/' + album.url %} {% set metaUrl = '/' + album.url %}