提交 46144e87 编写于 作者: fxy060608's avatar fxy060608

fix: sanitize asset filename

上级 505cb730
......@@ -218,7 +218,7 @@ export function assetFileNamesToFileName(
return hash
case '[name]':
return name
return sanitizeFileName(name)
}
throw new Error(
`invalid placeholder ${placeholder} in assetFileNames "${assetFileNames}"`
......@@ -229,6 +229,23 @@ export function assetFileNamesToFileName(
return fileName
}
// taken from https://github.com/rollup/rollup/blob/a8647dac0fe46c86183be8596ef7de25bc5b4e4b/src/utils/sanitizeFileName.ts
// https://datatracker.ietf.org/doc/html/rfc2396
// eslint-disable-next-line no-control-regex
const INVALID_CHAR_REGEX = /[\x00-\x1F\x7F<>*#"{}|^[\]`;?:&=+$,]/g
const DRIVE_LETTER_REGEX = /^[a-z]:/i
function sanitizeFileName(name: string): string {
const match = DRIVE_LETTER_REGEX.exec(name)
const driveLetter = match ? match[0] : ''
// A `:` is only allowed as part of a windows drive letter (ex: C:\foo)
// Otherwise, avoid them because they can refer to NTFS alternate data streams.
return (
driveLetter +
name.substring(driveLetter.length).replace(INVALID_CHAR_REGEX, '_')
)
}
/**
* Register an asset to be emitted as part of the bundle (if necessary)
* and returns the resolved public URL
......
......@@ -469,6 +469,10 @@ async function compileCSS(
if (preprocessResult.errors.length) {
throw preprocessResult.errors[0]
}
// TODO 升级
// if (preprocessResult.error) {
// throw preprocessResult.error
// }
code = preprocessResult.code
preprocessorMap = combineSourcemapsIfExists(
......@@ -554,69 +558,78 @@ async function compileCSS(
map: preprocessorMap,
}
}
// postcss is an unbundled dep and should be lazy imported
const postcssResult = await (await import('postcss'))
.default(postcssPlugins)
.process(code, {
...postcssOptions,
to: id,
from: id,
...(devSourcemap
? {
map: {
inline: false,
annotation: false,
// postcss may return virtual files
// we cannot obtain content of them, so this needs to be enabled
sourcesContent: true,
// when "prev: preprocessorMap", the result map may include duplicate filename in `postcssResult.map.sources`
// prev: preprocessorMap,
},
}
: {}),
})
// record CSS dependencies from @imports
for (const message of postcssResult.messages) {
if (message.type === 'dependency') {
deps.add(normalizePath(message.file as string))
} else if (message.type === 'dir-dependency') {
// https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#3-dependencies
const { dir, glob: globPattern = '**' } = message
const pattern =
normalizePath(path.resolve(path.dirname(id), dir)) + `/` + globPattern
const files = glob.sync(pattern, {
ignore: ['**/node_modules/**'],
let postcssResult: PostCSS.Result
try {
// postcss is an unbundled dep and should be lazy imported
postcssResult = await (await import('postcss'))
.default(postcssPlugins)
.process(code, {
...postcssOptions,
to: id,
from: id,
...(devSourcemap
? {
map: {
inline: false,
annotation: false,
// postcss may return virtual files
// we cannot obtain content of them, so this needs to be enabled
sourcesContent: true,
// when "prev: preprocessorMap", the result map may include duplicate filename in `postcssResult.map.sources`
// prev: preprocessorMap,
},
}
: {}),
})
for (let i = 0; i < files.length; i++) {
deps.add(files[i])
}
if (server) {
// register glob importers so we can trigger updates on file add/remove
if (!(id in (server as any)._globImporters)) {
;(server as any)._globImporters[id] = {
module: server.moduleGraph.getModuleById(id)!,
importGlobs: [],
// record CSS dependencies from @imports
for (const message of postcssResult.messages) {
if (message.type === 'dependency') {
deps.add(normalizePath(message.file as string))
} else if (message.type === 'dir-dependency') {
// https://github.com/postcss/postcss/blob/main/docs/guidelines/plugin.md#3-dependencies
const { dir, glob: globPattern = '**' } = message
const pattern =
normalizePath(path.resolve(path.dirname(id), dir)) + `/` + globPattern
const files = glob.sync(pattern, {
ignore: ['**/node_modules/**'],
})
for (let i = 0; i < files.length; i++) {
deps.add(files[i])
}
if (server) {
// register glob importers so we can trigger updates on file add/remove
if (!(id in (server as any)._globImporters)) {
;(server as any)._globImporters[id] = {
module: server.moduleGraph.getModuleById(id)!,
importGlobs: [],
}
}
;(server as any)._globImporters[id].importGlobs.push({
base: config.root,
pattern,
})
}
;(server as any)._globImporters[id].importGlobs.push({
base: config.root,
pattern,
})
}
} else if (message.type === 'warning') {
let msg = `[vite:css] ${message.text}`
if (message.line && message.column) {
msg += `\n${generateCodeFrame(code, {
line: message.line,
column: message.column,
})}`
} else if (message.type === 'warning') {
let msg = `[vite:css] ${message.text}`
if (message.line && message.column) {
msg += `\n${generateCodeFrame(code, {
line: message.line,
column: message.column,
})}`
}
config.logger.warn(colors.yellow(msg))
}
config.logger.warn(colors.yellow(msg))
}
} catch (e: any) {
e.message = `[postcss] ${e.message}`
e.code = code
e.loc = {
column: e.column,
line: e.line,
}
throw e
}
if (!devSourcemap) {
return {
ast: postcssResult,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册