You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

74 lines
1.8 KiB

/*!
* resolve-path
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2015-2018 Douglas Christopher Wilson
* MIT Licensed
*/
/**
* ES Module 转换版本
* 路径解析工具,防止路径遍历攻击
*/
import createError from 'http-errors';
import { join, normalize, resolve, sep } from 'path';
import pathIsAbsolute from 'path-is-absolute';
/**
* 模块变量
* @private
*/
const UP_PATH_REGEXP = /(?:^|[\/])\.\.(?:[\/]|$)/;
/**
* 解析相对路径到根路径
* @param {string} rootPath - 根目录路径
* @param {string} relativePath - 相对路径
* @returns {string} 解析后的绝对路径
* @public
*/
function resolvePath(rootPath, relativePath) {
let path = relativePath;
let root = rootPath;
// root是可选的,类似于root.resolve
if (arguments.length === 1) {
path = rootPath;
root = process.cwd();
}
if (root == null) {
throw new TypeError('argument rootPath is required');
}
if (typeof root !== 'string') {
throw new TypeError('argument rootPath must be a string');
}
if (path == null) {
throw new TypeError('argument relativePath is required');
}
if (typeof path !== 'string') {
throw new TypeError('argument relativePath must be a string');
}
// 包含NULL字节是恶意的
if (path.indexOf('\0') !== -1) {
throw createError(400, 'Malicious Path');
}
// 路径绝不能是绝对路径
if (pathIsAbsolute.posix(path) || pathIsAbsolute.win32(path)) {
throw createError(400, 'Malicious Path');
}
// 路径超出根目录
if (UP_PATH_REGEXP.test(normalize('.' + sep + path))) {
throw createError(403);
}
// 拼接相对路径
return normalize(join(resolve(root), path));
}
export default resolvePath;