35 lines
1005 B
JavaScript
35 lines
1005 B
JavaScript
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
|
|
};
|