mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-04 11:52:25 +00:00
Refactor qrcode.js to use DOM methods instead of innerHTML
- Replaces unsafe innerHTML usage with document.createElement and appendChild in the table drawing fallback. - Adds a unit test `tests/qrcode_table_fallback.test.mjs` to verify the table generation logic using JSDOM. - Addresses a potential security vulnerability where HTML injection could occur (though unlikely in this specific context, it is best practice). - Updates package.json to include jsdom in devDependencies (if not already present). Co-authored-by: PR0M3TH3AN <[email protected]>
This commit is contained in:
1 parent
9913e484ab
commit
0fcfc6009f
2 files changed
+61
-9
No files matched your search
+17
-9
@@ -336,7 +336,14 @@ if (hasDocument) {
|
||||
var nCount = oQRCode.getModuleCount();
|
||||
var nWidth = Math.floor(_htOption.width / nCount);
|
||||
var nHeight = Math.floor(_htOption.height / nCount);
|
||||
var aHTML = ['<table class="qr-code__table">'];
|
||||
|
||||
// Clear existing content
|
||||
while (_el.firstChild) {
|
||||
_el.removeChild(_el.firstChild);
|
||||
}
|
||||
|
||||
var elTable = document.createElement("table");
|
||||
elTable.className = "qr-code__table";
|
||||
|
||||
updateQrCodeContainerStyles(_el, {
|
||||
colorDark: _htOption.colorDark,
|
||||
@@ -347,23 +354,22 @@ if (hasDocument) {
|
||||
});
|
||||
|
||||
for (var row = 0; row < nCount; row++) {
|
||||
aHTML.push('<tr>');
|
||||
var elRow = document.createElement("tr");
|
||||
|
||||
for (var col = 0; col < nCount; col++) {
|
||||
var cellClass = oQRCode.isDark(row, col)
|
||||
var elCell = document.createElement("td");
|
||||
elCell.className = oQRCode.isDark(row, col)
|
||||
? "qr-code__cell qr-code__cell--dark"
|
||||
: "qr-code__cell";
|
||||
aHTML.push('<td class="' + cellClass + '"></td>');
|
||||
elRow.appendChild(elCell);
|
||||
}
|
||||
|
||||
aHTML.push('</tr>');
|
||||
elTable.appendChild(elRow);
|
||||
}
|
||||
|
||||
aHTML.push('</table>');
|
||||
_el.innerHTML = aHTML.join('');
|
||||
_el.appendChild(elTable);
|
||||
|
||||
// Fix the margin values as real size.
|
||||
var elTable = _el.childNodes[0];
|
||||
var nLeftMarginTable = (_htOption.width - (nCount * nWidth)) / 2;
|
||||
var nTopMarginTable = (_htOption.height - (nCount * nHeight)) / 2;
|
||||
|
||||
@@ -378,7 +384,9 @@ if (hasDocument) {
|
||||
* Clear the QRCode
|
||||
*/
|
||||
Drawing.prototype.clear = function () {
|
||||
this._el.innerHTML = '';
|
||||
while (this._el.firstChild) {
|
||||
this._el.removeChild(this._el.firstChild);
|
||||
}
|
||||
};
|
||||
|
||||
return Drawing;
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert';
|
||||
import { JSDOM } from 'jsdom';
|
||||
|
||||
test('QR Code Table Fallback', async (t) => {
|
||||
// Setup JSDOM
|
||||
const dom = new JSDOM(`<!DOCTYPE html><body><div id="qrcode"></div></body>`);
|
||||
|
||||
// Override globals to simulate browser environment provided by JSDOM
|
||||
// We need to override what setup-localstorage.mjs might have set
|
||||
global.window = dom.window;
|
||||
global.document = dom.window.document;
|
||||
global.HTMLStyleElement = dom.window.HTMLStyleElement;
|
||||
global.HTMLElement = dom.window.HTMLElement;
|
||||
|
||||
// Copy other properties if needed, but these should be enough for qrcode.js
|
||||
|
||||
// Ensure CanvasRenderingContext2D is NOT defined to trigger the table fallback
|
||||
if (global.CanvasRenderingContext2D) {
|
||||
delete global.CanvasRenderingContext2D;
|
||||
}
|
||||
if (global.window.CanvasRenderingContext2D) {
|
||||
delete global.window.CanvasRenderingContext2D;
|
||||
}
|
||||
|
||||
// Dynamically import the module to ensure it uses the current environment
|
||||
const { createQrCode } = await import('../js/utils/qrcode.js');
|
||||
|
||||
const el = global.document.getElementById('qrcode');
|
||||
|
||||
// Create QR code
|
||||
createQrCode(el, { text: "test", width: 100, height: 100 });
|
||||
|
||||
// Verify table is used (this confirms we hit the refactored code path)
|
||||
const table = el.querySelector('table');
|
||||
assert.ok(table, "Table should be created when canvas is not supported");
|
||||
assert.ok(table.classList.contains('qr-code__table'), "Table should have correct class");
|
||||
|
||||
const rows = table.querySelectorAll('tr');
|
||||
assert.ok(rows.length > 0, "Should have rows");
|
||||
|
||||
const cells = table.querySelectorAll('td');
|
||||
assert.ok(cells.length > 0, "Should have cells");
|
||||
});
|
||||
Reference in new issue
Block a user