Add readFile function
This commit is contained in:
parent
3fedd5bb77
commit
1f693003ed
2 changed files with 164 additions and 152 deletions
|
@ -7,7 +7,7 @@ import clone from 'clone';
|
|||
import express from 'express';
|
||||
import { validateStyleMin } from '@maplibre/maplibre-gl-style-spec';
|
||||
|
||||
import { fixUrl, allowedOptions } from './utils.js';
|
||||
import { fixUrl, allowedOptions, readFile } from './utils.js';
|
||||
|
||||
const httpTester = /^https?:\/\//i;
|
||||
const allowedSpriteFormats = allowedOptions(['png', 'json']);
|
||||
|
@ -101,7 +101,9 @@ export const serve_style = {
|
|||
* @param {string} req.params.format - Format of the sprite file, 'png' or 'json'.
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
app.get(`/:id/sprite{/:spriteID}{@:scale}{.:format}`, (req, res, next) => {
|
||||
app.get(
|
||||
`/:id/sprite{/:spriteID}{@:scale}{.:format}`,
|
||||
async (req, res, next) => {
|
||||
const { spriteID = 'default', id, format, scale } = req.params;
|
||||
const sanitizedId = String(id).replace(/\n|\r/g, '');
|
||||
const sanitizedScale = scale ? String(scale).replace(/\n|\r/g, '') : '';
|
||||
|
@ -131,7 +133,9 @@ export const serve_style = {
|
|||
);
|
||||
return res.sendStatus(404);
|
||||
}
|
||||
const sprite = item.spritePaths.find((sprite) => sprite.id === spriteID);
|
||||
const sprite = item.spritePaths.find(
|
||||
(sprite) => sprite.id === spriteID,
|
||||
);
|
||||
const spriteScale = allowedSpriteScales(scale);
|
||||
if (!sprite || spriteScale === null) {
|
||||
if (verbose)
|
||||
|
@ -159,18 +163,8 @@ export const serve_style = {
|
|||
const sanitizedSpritePath = sprite.path.replace(/^(\.\.\/)+/, '');
|
||||
const filename = `${sanitizedSpritePath}${spriteScale}.${validatedFormat}`;
|
||||
if (verbose) console.log(`Loading sprite from: %s`, filename);
|
||||
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||
fs.readFile(filename, (err, data) => {
|
||||
if (err) {
|
||||
if (verbose)
|
||||
console.error(
|
||||
'Sprite load error: %s, Error: %s',
|
||||
filename,
|
||||
String(err),
|
||||
);
|
||||
return res.sendStatus(404);
|
||||
}
|
||||
try {
|
||||
const data = await readFile(filename);
|
||||
|
||||
if (validatedFormat === 'json') {
|
||||
res.header('Content-type', 'application/json');
|
||||
|
@ -187,8 +181,18 @@ export const serve_style = {
|
|||
);
|
||||
res.set({ 'Last-Modified': item.lastModified });
|
||||
return res.send(data);
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
if (verbose) {
|
||||
console.error(
|
||||
'Sprite load error: %s, Error: %s',
|
||||
filename,
|
||||
String(err),
|
||||
);
|
||||
}
|
||||
return res.sendStatus(404);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
return app;
|
||||
},
|
||||
|
|
56
src/utils.js
56
src/utils.js
|
@ -185,6 +185,24 @@ export function fixTileJSONCenter(tileJSON) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file and returns a Promise with the file data.
|
||||
* @param {string} filename - Path to the file to read.
|
||||
* @returns {Promise<Buffer>} - A Promise that resolves with the file data as a Buffer or rejects with an error.
|
||||
*/
|
||||
export function readFile(filename) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||
fs.readFile(filename, (err, data) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(data);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves font data for a given font and range.
|
||||
* @param {object} allowedFonts - An object of allowed fonts.
|
||||
|
@ -194,22 +212,16 @@ export function fixTileJSONCenter(tileJSON) {
|
|||
* @param {object} [fallbacks] - Optional fallback font list.
|
||||
* @returns {Promise<Buffer>} A promise that resolves with the font data Buffer or rejects with an error.
|
||||
*/
|
||||
function getFontPbf(allowedFonts, fontPath, name, range, fallbacks) {
|
||||
return new Promise((resolve, reject) => {
|
||||
async function getFontPbf(allowedFonts, fontPath, name, range, fallbacks) {
|
||||
if (!allowedFonts || (allowedFonts[name] && fallbacks)) {
|
||||
const fontMatch = name?.match(/^[\w\s-]+$/);
|
||||
const sanitizedName = fontMatch?.[0] || 'invalid';
|
||||
if (
|
||||
!name ||
|
||||
typeof name !== 'string' ||
|
||||
name.trim() === '' ||
|
||||
!fontMatch
|
||||
) {
|
||||
if (!name || typeof name !== 'string' || name.trim() === '' || !fontMatch) {
|
||||
console.error(
|
||||
'ERROR: Invalid font name: %s',
|
||||
sanitizedName.replace(/\n|\r/g, ''),
|
||||
);
|
||||
return reject('Invalid font name');
|
||||
throw new Error('Invalid font name');
|
||||
}
|
||||
|
||||
const rangeMatch = range?.match(/^[\d-]+$/);
|
||||
|
@ -219,20 +231,23 @@ function getFontPbf(allowedFonts, fontPath, name, range, fallbacks) {
|
|||
'ERROR: Invalid range: %s',
|
||||
sanitizedRange.replace(/\n|\r/g, ''),
|
||||
);
|
||||
return reject('Invalid range');
|
||||
throw new Error('Invalid range');
|
||||
}
|
||||
const filename = path.join(
|
||||
fontPath,
|
||||
sanitizedName,
|
||||
`${sanitizedRange}.pbf`,
|
||||
);
|
||||
|
||||
if (!fallbacks) {
|
||||
fallbacks = clone(allowedFonts || {});
|
||||
}
|
||||
delete fallbacks[name];
|
||||
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
||||
fs.readFile(filename, (err, data) => {
|
||||
if (err) {
|
||||
|
||||
try {
|
||||
const data = await readFile(filename);
|
||||
return data;
|
||||
} catch (err) {
|
||||
console.error(
|
||||
'ERROR: Font not found: %s, Error: %s',
|
||||
filename.replace(/\n|\r/g, ''),
|
||||
|
@ -258,21 +273,14 @@ function getFontPbf(allowedFonts, fontPath, name, range, fallbacks) {
|
|||
sanitizedName,
|
||||
);
|
||||
delete fallbacks[fallbackName];
|
||||
getFontPbf(null, fontPath, fallbackName, range, fallbacks).then(
|
||||
resolve,
|
||||
reject,
|
||||
);
|
||||
return getFontPbf(null, fontPath, fallbackName, range, fallbacks);
|
||||
} else {
|
||||
reject('Font load error');
|
||||
throw new Error('Font load error');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
resolve(data);
|
||||
throw new Error('Font not allowed');
|
||||
}
|
||||
});
|
||||
} else {
|
||||
reject('Font not allowed');
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Combines multiple font pbf buffers into one.
|
||||
|
|
Loading…
Reference in a new issue