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
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;
|
|
|