Refactored jQuery DOM element creation

using plain JavaScript, to ensure text nodes are sanitized
This commit is contained in:
El RIDO 2025-10-25 12:56:55 +02:00
parent 1f5ed30a63
commit 68972322d9
No known key found for this signature in database
GPG key ID: 0F5C940A6BD81F92
2 changed files with 45 additions and 49 deletions

View file

@ -3028,7 +3028,8 @@ jQuery.PrivateBin = (function($, RawDeflate) {
attachmentLink.attr('download', fileName);
const fileSize = Helper.formatBytes(decodedData.length);
template.append(`(${fileName}, ${fileSize})`);
const fileInfo = document.createTextNode(` (${fileName}, ${fileSize})`);
template[0].appendChild(fileInfo);
}
// sanitize SVG preview
@ -3323,44 +3324,38 @@ jQuery.PrivateBin = (function($, RawDeflate) {
const alreadyIncludesCurrentAttachment = $targetElement.find(`[src='${blobUrl}']`).length > 0;
if (blobUrl && !alreadyIncludesCurrentAttachment) {
if (mimeType.match(/^image\//i)) {
$targetElement.append(
$(document.createElement('img'))
.attr('src', blobUrl)
.attr('class', 'img-thumbnail')
);
} else if (mimeType.match(/^video\//i)) {
$targetElement.append(
$(document.createElement('video'))
.attr('controls', 'true')
.attr('autoplay', 'true')
.attr('class', 'img-thumbnail')
.append($(document.createElement('source'))
.attr('type', mimeType)
.attr('src', blobUrl))
);
} else if (mimeType.match(/^audio\//i)) {
$targetElement.append(
$(document.createElement('audio'))
.attr('controls', 'true')
.attr('autoplay', 'true')
.append($(document.createElement('source'))
.attr('type', mimeType)
.attr('src', blobUrl))
);
} else if (mimeType.match(/\/pdf/i)) {
if (mimeType.toLowerCase().startsWith('image/')) {
const image = document.createElement('img');
image.setAttribute('src', blobUrl);
image.setAttribute('class', 'img-thumbnail');
$targetElement[0].appendChild(image);
} else if (mimeType.toLowerCase().startsWith('video/')) {
const video = document.createElement('video');
video.setAttribute('controls', 'true');
video.setAttribute('autoplay', 'true');
video.setAttribute('class', 'img-thumbnail');
const source = document.createElement('source');
source.setAttribute('type', mimeType);
source.setAttribute('src', blobUrl);
video.appendChild(source);
$targetElement[0].appendChild(video);
} else if (mimeType.toLowerCase().startsWith('audio/')) {
const audio = document.createElement('audio');
audio.setAttribute('controls', 'true');
audio.setAttribute('autoplay', 'true');
const source = document.createElement('source');
source.setAttribute('type', mimeType);
source.setAttribute('src', blobUrl);
audio.appendChild(source);
$targetElement[0].appendChild(audio);
} else if (mimeType.toLowerCase().endsWith('/pdf')) {
const embed = document.createElement('embed');
embed.setAttribute('src', blobUrl);
embed.setAttribute('type', 'application/pdf');
embed.setAttribute('class', 'pdfPreview');
// Fallback for browsers, that don't support the vh unit
const clientHeight = $(window).height();
$targetElement.append(
$(document.createElement('embed'))
.attr('src', blobUrl)
.attr('type', 'application/pdf')
.attr('class', 'pdfPreview')
.css('height', clientHeight)
);
embed.style.height = window.innerHeight + 'px';
$targetElement[0].appendChild(embed);
}
}
};
@ -3638,8 +3633,9 @@ jQuery.PrivateBin = (function($, RawDeflate) {
if (nickname.length > 0) {
$commentEntry.find('span.nickname').text(nickname);
} else {
$commentEntry.find('span.nickname').html('<i></i>');
I18n._($commentEntry.find('span.nickname i'), 'Anonymous');
const anonCommenter = document.createElement('em');
anonCommenter.textContent = I18n._('Anonymous');
$commentEntry.find('span.nickname')[0].appendChild(anonCommenter);
}
// set date
@ -3652,14 +3648,10 @@ jQuery.PrivateBin = (function($, RawDeflate) {
// if an avatar is available, display it
const icon = comment.getIcon();
if (icon) {
$commentEntry.find('span.nickname')
.before(
'<img src="' + icon + '" class="vizhash" /> '
);
$(document).on('languageLoaded', function () {
$commentEntry.find('img.vizhash')
.prop('title', I18n._('Avatar generated from IP address'));
});
const image = document.createElement('img');
image.setAttribute('src', icon);
image.setAttribute('class', 'vizhash');
$commentEntry.find('span.nickname').prepend(image);
}
// starting point (default value/fallback)
@ -5493,6 +5485,10 @@ jQuery.PrivateBin = (function($, RawDeflate) {
plaintexts[i][1]
);
}
$(document).on('languageLoaded', function () {
$('#commentcontainer').find('img.vizhash')
.prop('title', I18n._('Avatar generated from IP address'));
});
});
}

View file

@ -119,7 +119,7 @@ class Configuration
'js/kjua-0.10.0.js' => 'sha512-BYj4xggowR7QD150VLSTRlzH62YPfhpIM+b/1EUEr7RQpdWAGKulxWnOvjFx1FUlba4m6ihpNYuQab51H6XlYg==',
'js/legacy.js' => 'sha512-iP69buypAHBJOgt7AyDcfaelVxBES9/k3dVfd6hPxTRizVRH2dijEpMWCt1D8OH4FNgytKsDI/J7+9y7IgXPaA==',
'js/prettify.js' => 'sha512-puO0Ogy++IoA2Pb9IjSxV1n4+kQkKXYAEUtVzfZpQepyDPyXk8hokiYDS7ybMogYlyyEIwMLpZqVhCkARQWLMg==',
'js/privatebin.js' => 'sha512-4JZRpxpswphn0BaWaTtUWacCiqAGOYoH3M4wG6A+vkEFfyZfA9upJ6CqAHpKVA9gNj5o0BSuj8RRwPVbO478IA==',
'js/privatebin.js' => 'sha512-brvgUw0Hn7J25GyC2Dk1aihy61tqH2KWDQWV/SZ9qpTTamiJFWrYBcoYWJqoIldtl+uJl2WM+6kdagyUo1TtLw==',
'js/purify-3.3.0.js' => 'sha512-lsHD5zxs4lu/NDzaaibe27Vd2t7Cy9JQ3qDHUvDfb4oZvKoWDNEhwUY+4bT3R68cGgpgCYp8U1x2ifeVxqurdQ==',
'js/rawinflate-0.3.js' => 'sha512-g8uelGgJW9A/Z1tB6Izxab++oj5kdD7B4qC7DHwZkB6DGMXKyzx7v5mvap2HXueI2IIn08YlRYM56jwWdm2ucQ==',
'js/showdown-2.1.0.js' => 'sha512-WYXZgkTR0u/Y9SVIA4nTTOih0kXMEd8RRV6MLFdL6YU8ymhR528NLlYQt1nlJQbYz4EW+ZsS0fx1awhiQJme1Q==',