diff --git a/static/skin/viewer.js b/static/skin/viewer.js
index 10e8b48d9..24050a3b7 100644
--- a/static/skin/viewer.js
+++ b/static/skin/viewer.js
@@ -43,17 +43,27 @@ function gotoMainPageOfCurrentBook() {
}
function gotoUrl(url) {
- contentIframe.src = url;
+ contentIframe.src = root + url;
}
function gotoRandomPage() {
- gotoUrl(`${root}/random?content=${currentBook}`);
+ gotoUrl(`/random?content=${currentBook}`);
}
function performSearch() {
const searchbox = document.getElementById('kiwixsearchbox');
const q = encodeURIComponent(searchbox.value);
- gotoUrl(`${root}/search?books.name=${currentBook}&pattern=${q}`);
+ gotoUrl(`/search?books.name=${currentBook}&pattern=${q}`);
+}
+
+function makeJSLink(jsCodeString, linkText, linkAttr="") {
+ // Values of the href attribute are assumed by the browser to be
+ // fully URI-encoded (no matter what the scheme is). Therefore, in
+ // order to prevent the browser from decoding any URI-encoded parts
+ // in the JS code we have to URI-encode a second time.
+ // (see https://stackoverflow.com/questions/33721510)
+ const uriEncodedJSCode = encodeURIComponent(jsCodeString);
+ return `${linkText}`;
}
function suggestionsApiURL()
@@ -336,20 +346,21 @@ function setupSuggestions() {
},
resultItem: {
element: (item, data) => {
- let searchLink;
+ const uriEncodedBookName = encodeURIComponent(currentBook);
+ let url;
if (data.value.kind == "path") {
- searchLink = `${root}/${currentBook}/${htmlDecode(data.value.path)}`;
+ const path = encodeURIComponent(htmlDecode(data.value.path));
+ url = `/${uriEncodedBookName}/${path}`;
} else {
- searchLink = `${root}/search?content=${encodeURIComponent(currentBook)}&pattern=${encodeURIComponent(htmlDecode(data.value.value))}`;
+ const pattern = encodeURIComponent(htmlDecode(data.value.value));
+ url = `/search?content=${uriEncodedBookName}&pattern=${pattern}`;
}
- const jsAction = `gotoUrl('${searchLink}')`;
- // Values of the href attribute are assumed by the browser to be
- // fully URI-encoded (no matter what the scheme is). Therefore, in
- // order to prevent the browser from decoding the URI-encoded parts
- // of searchLink we have to URI-encode a second time.
- // (see https://stackoverflow.com/questions/33721510)
- const jsActionURIEncoded = encodeURIComponent(jsAction);
- item.innerHTML = `${htmlDecode(data.value.label)}`;
+ // url can't contain any double quote and/or backslash symbols
+ // since they should have been URI-encoded. Therefore putting it
+ // inside double quotes should result in valid javascript.
+ const jsAction = `gotoUrl("${url}")`;
+ const linkText = htmlDecode(data.value.label);
+ item.innerHTML = makeJSLink(jsAction, linkText, 'class="suggest"');
},
highlight: "autoComplete_highlight",
selected: "autoComplete_selected"
diff --git a/test/server.cpp b/test/server.cpp
index 2c6156c23..9b2da29a8 100644
--- a/test/server.cpp
+++ b/test/server.cpp
@@ -69,7 +69,7 @@ const ResourceCollection resources200Compressible{
{ DYNAMIC_CONTENT, "/ROOT/skin/taskbar.css" },
{ STATIC_CONTENT, "/ROOT/skin/taskbar.css?cacheid=216d6b5d" },
{ DYNAMIC_CONTENT, "/ROOT/skin/viewer.js" },
- { STATIC_CONTENT, "/ROOT/skin/viewer.js?cacheid=0933a233" },
+ { STATIC_CONTENT, "/ROOT/skin/viewer.js?cacheid=23966598" },
{ DYNAMIC_CONTENT, "/ROOT/skin/fonts/Poppins.ttf" },
{ STATIC_CONTENT, "/ROOT/skin/fonts/Poppins.ttf?cacheid=af705837" },
{ DYNAMIC_CONTENT, "/ROOT/skin/fonts/Roboto.ttf" },
@@ -291,7 +291,7 @@ R"EXPECTEDRESULT(
-
+
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";