const path = require('path'); function isPathInside(parent, child) { const relativePath = path.relative(parent, child); return relativePath === '' || (!relativePath.startsWith('..') && !path.isAbsolute(relativePath)); } function normalizeVirtualPath(rawPath) { if (typeof rawPath !== 'string') return null; let decoded = rawPath; try { decoded = decodeURIComponent(rawPath); } catch { // The traversal checks below still apply to malformed encoded input. } if (decoded.includes('\x00') || decoded.toLowerCase().includes('%00')) return null; const unifiedPath = decoded.replace(/\\/g, '/'); if (/(^|\/)\.\.(\/|$)/.test(unifiedPath)) return null; let normalized = path.posix.normalize(unifiedPath); if (normalized === '' || normalized === '.') normalized = '/'; if (!normalized.startsWith('/')) normalized = `/${normalized}`; normalized = normalized.replace(/\/+$/g, ''); return normalized || '/'; } module.exports = { isPathInside, normalizeVirtualPath };