fix(kml-import): address PR #488 review issues

- Strip BOM (U+FEFF) from 14 translation files injected by editor
- Guard KMZ unpack against zip-bomb: check entry.uncompressedSize against
  50 MB cap (KMZ_DECOMPRESSED_SIZE_LIMIT) before calling .buffer();
  limit is an exported constant so tests can override it
- Fix non-BMP HTML entity decoding: replace String.fromCharCode with
  String.fromCodePoint + 0x10FFFF bounds check so emoji like 😀
  round-trip correctly
- Switch KML namespace stripping from regex to fast-xml-parser's
  removeNSPrefix option; XMLValidator accepts namespaced XML natively,
  making the pre-strip step unnecessary
- Remove dead skippedCount overwrite after transaction; per-loop
  increment already tracks it alongside per-item error messages
- Type multer req.file as Express.Multer.File on both /import/gpx
  and /import/map routes instead of (req as any).file
- Add unit tests: emoji entity decoding (decimal + hex), KMZ zip-bomb
  rejection, KMZ-with-no-KML rejection
This commit is contained in:
jubnl
2026-04-15 05:16:47 +02:00
parent a1a7795945
commit 801ffbfb7b
19 changed files with 103 additions and 41 deletions
+2 -2
View File
@@ -63,7 +63,7 @@ router.post('/import/gpx', authenticate, requireTripAccess, uploadMulter.single(
return res.status(403).json({ error: 'No permission' });
const { tripId } = req.params;
const file = (req as any).file;
const file = req.file as Express.Multer.File | undefined;
if (!file) return res.status(400).json({ error: 'No file uploaded' });
const created = importGpx(tripId, file.buffer);
@@ -84,7 +84,7 @@ router.post('/import/map', authenticate, requireTripAccess, uploadMulter.single(
}
const { tripId } = req.params;
const file = (req as any).file;
const file = req.file as Express.Multer.File | undefined;
if (!file) return res.status(400).json({ error: 'No file uploaded' });
try {