mirror of https://github.com/kiwix/libkiwix.git
Proper HTML encoding/decoding of tags in the frontend
- Tags in the OPDS feed are HTML encoded and must be decoded. - Tag values must be HTML encoded when injected into the DOM: * When the injection is done by setting the innerHTML attribute of a DOM element, HTML encoding must be done explicitly (since that text is going to be parsed as HTML). * When the tag value is expanded into a string that is then set as an attribute of a DOM element via the setAttribute() method, no HTML encoding must be done (since Element.setAttribute() directly sets that value and no HTML decoding is involved in that operation).
This commit is contained in:
parent
fbcd160efd
commit
846404e959
|
@ -51,8 +51,8 @@
|
|||
, "torrent-download-link-text": "BitTorrent"
|
||||
, "torrent-download-alt-text": "Download via BitTorrent"
|
||||
, "library-opds-feed-all-entries": "Library OPDS Feed - All entries"
|
||||
, "filter-by-tag": "Filter by tag \"{{TAG}}\""
|
||||
, "stop-filtering-by-tag": "Stop filtering by tag \"{{TAG}}\""
|
||||
, "filter-by-tag": "Filter by tag \"{{{TAG}}}\""
|
||||
, "stop-filtering-by-tag": "Stop filtering by tag \"{{{TAG}}}\""
|
||||
, "library-opds-feed-parameterised": "Library OPDS Feed - entries matching {{#LANG}}\nLanguage: {{LANG}} {{/LANG}}{{#CATEGORY}}\nCategory: {{CATEGORY}} {{/CATEGORY}}{{#TAG}}\nTag: {{TAG}} {{/TAG}}{{#Q}}\nQuery: {{Q}} {{/Q}}"
|
||||
, "welcome-to-kiwix-server": "Welcome to Kiwix Server"
|
||||
, "download-links-heading": "Download links for <b><i>{{BOOK_TITLE}}</i></b>"
|
||||
|
|
|
@ -105,6 +105,14 @@
|
|||
return '';
|
||||
}
|
||||
|
||||
// Borrowed from https://stackoverflow.com/a/1912522
|
||||
function htmlDecode(input){
|
||||
var e = document.createElement('textarea');
|
||||
e.innerHTML = input;
|
||||
// handle case of empty input
|
||||
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
|
||||
}
|
||||
|
||||
function htmlEncode(str) {
|
||||
return str.replace(/[\u00A0-\u9999<>\&]/gim, (i) => `&#${i.charCodeAt(0)};`);
|
||||
}
|
||||
|
@ -121,9 +129,14 @@
|
|||
|
||||
function generateTagLink(tagValue) {
|
||||
tagValue = tagValue.toLowerCase();
|
||||
const htmlEncodedTagValue = htmlEncode(tagValue);
|
||||
const tagMessage = $t("filter-by-tag", {TAG: tagValue});
|
||||
return `<span class='tag__link' aria-label='${tagMessage}' title='${tagMessage}' data-tag=${htmlEncodedTagValue}>${htmlEncodedTagValue}</span>`
|
||||
const spanElement = document.createElement("span");
|
||||
spanElement.className = 'tag__link';
|
||||
spanElement.setAttribute('aria-label', tagMessage);
|
||||
spanElement.setAttribute('title', tagMessage);
|
||||
spanElement.setAttribute('data-tag', tagValue);
|
||||
spanElement.innerHTML = htmlEncode(tagValue);
|
||||
return spanElement.outerHTML;
|
||||
}
|
||||
|
||||
function generateBookHtml(book, sort = false) {
|
||||
|
@ -144,7 +157,7 @@
|
|||
const mulLangList = langCodesList.filter(x => languages.hasOwnProperty(x)).map(x => languages[x]);
|
||||
language = mulLangList.join(', ');
|
||||
}
|
||||
const tags = getInnerHtml(book, 'tags');
|
||||
const tags = htmlDecode(getInnerHtml(book, 'tags'));
|
||||
const tagList = tags.split(';').filter(tag => {return !(tag.startsWith('_'))});
|
||||
const tagFilterLinks = tagList.map((tagValue) => generateTagLink(tagValue));
|
||||
const tagHtml = tagFilterLinks.join(' | ');
|
||||
|
@ -492,7 +505,7 @@
|
|||
function addTagElement(tagValue, resetFilter) {
|
||||
const tagElement = document.getElementsByClassName('tagFilterLabel')[0];
|
||||
tagElement.style.display = 'inline-block';
|
||||
tagElement.innerHTML = `${tagValue}`;
|
||||
tagElement.innerHTML = htmlEncode(tagValue);
|
||||
const tagMessage = $t("stop-filtering-by-tag", {TAG: tagValue});
|
||||
tagElement.setAttribute('aria-label', tagMessage);
|
||||
tagElement.setAttribute('title', tagMessage);
|
||||
|
|
Loading…
Reference in New Issue