3
0
mirror of https://github.com/snipe/snipe-it.git synced 2026-08-18 11:15:42 +00:00

Added Dejavu support

This commit is contained in:
snipe
2026-07-07 00:19:00 +01:00
parent d151c8c5a0
commit 62315f77ff
5 changed files with 55 additions and 12 deletions

File diff suppressed because one or more lines are too long

View File

@ -78,5 +78,5 @@
"/js/dist/bootstrap-table-en-US.min.js": "/js/dist/bootstrap-table-en-US.min.js?id=6d0de12d91548ba2cd80b868838ce5fa",
"/js/dist/Chart.min.js": "/js/dist/Chart.min.js?id=9b1ae20c4c7048d6e4a1b2e1aee7fb31",
"/css/dist/bootstrap-table.css": "/css/dist/bootstrap-table.css?id=82b56573f8098e439bf14ccb4530de6e",
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=e35995588f9ef97c7b8b13f175af72eb"
"/js/dist/bootstrap-table.js": "/js/dist/bootstrap-table.js?id=e1531ba4cea2a4a3b966751c2870a8e0"
}

View File

@ -22,16 +22,23 @@ const path = require('path');
const outPath = path.join(__dirname, 'jspdf-dejavu-fonts.js');
const ttfDir = path.join(__dirname, '..', '..', '..', 'node_modules', 'dejavu-fonts-ttf', 'ttf');
// jsPDF/autotable looks fonts up by (name, style) where `style` is one of
// 'normal' | 'italic' | 'bold' | 'bolditalic'. Registering the bold face
// with `style: 'normal', weight: 'bold'` (jsPDF's 4-arg addFont form) makes
// autotable's `getFont('DejaVuSans', 'bold')` MISS — it looks up by the
// style slot, not the weight slot. So the second face has to declare
// `style: 'bold'` directly. If you add italic/bolditalic TTFs in the
// future, list them here the same way (`style: 'italic'`, etc.).
const faces = [
{ file: 'DejaVuSans.ttf', style: 'normal', weight: 'normal' },
{ file: 'DejaVuSans-Bold.ttf', style: 'normal', weight: 'bold' },
{ file: 'DejaVuSans.ttf', style: 'normal' },
{ file: 'DejaVuSans-Bold.ttf', style: 'bold' },
];
const registrations = faces.map(({ file, style, weight }) => {
const registrations = faces.map(({ file, style }) => {
const buf = fs.readFileSync(path.join(ttfDir, file));
const b64 = buf.toString('base64');
return ` this.addFileToVFS(${JSON.stringify(file)}, ${JSON.stringify(b64)});\n` +
` this.addFont(${JSON.stringify(file)}, 'DejaVuSans', ${JSON.stringify(style)}, ${JSON.stringify(weight)});`;
` this.addFont(${JSON.stringify(file)}, 'DejaVuSans', ${JSON.stringify(style)});`;
}).join('\n');
const out = `/**

File diff suppressed because one or more lines are too long

View File

@ -546,11 +546,47 @@
}
};
// tableWidth: 'wrap',
// the following callback method is necessary to prevent XSS vulnerabilities
// (this is taken from Bootstrap Tables's default wrapper around jQuery Table Export)
// ⚠️ SECURITY: DO NOT change the wrapping of `.text()` inside
// `htmlEncodeForExport(...)` below without reading this entire
// block. The bare `.text()` was the previous shape and it is
// an XSS.
//
// XSS defense on export cell data. The tableExport plugin's
// E function (see bundled bootstrap-table.js around line 32110)
// pipes our return value through jQuery's .html() setter on a
// scratch <div> before serializing. If we return raw text that
// happens to look like HTML (e.g. a column titled
// `<img src=x onerror=alert(1)>`), that .html() call parses it
// and instantiates a real <img onerror=...> element, firing the
// payload as soon as the user clicks Export.
//
// Encoding the returned string turns any tag-shaped characters
// into entity refs; the downstream .html() call then treats
// them as text-content (browser text-decodes back to chars in a
// text-node, no elements created), and the final PDF/CSV output
// still shows the visible text the header displayed on-screen.
//
// Repro before the fix (kept as a regression pin):
// 1. Create a custom field named `<img src=x onerror=alert(1)>`
// 2. Visit the assets index (header shows the string as text)
// 3. Export → CSV (or PDF): alert(1) fires because tableExport
// re-injects our returned text via .html() on a scratch div.
// If a future edit here reintroduces the bug, that exact repro
// will fire alert(1) again. See the trap script in XSS_TRAP.md
// at the project root for the observer that surfaced the vector.
var htmlEncodeForExport = function (value) {
if (value == null) return '';
return String(value)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
};
export_options['onCellHtmlData'] = function (cell, rowIndex, colIndex, htmlData) {
if (cell.is('th')) {
return cell.find('.th-inner').text()
// ⚠️ MUST stay wrapped in htmlEncodeForExport(). See block above.
return htmlEncodeForExport(cell.find('.th-inner').text());
}
// Convert <br> tags to newlines so that line breaks in notes and
// textarea fields survive HTML-stripping during export