Skip to content

Commit

Permalink
fix: escape character in string regexp match (#7834)
Browse files Browse the repository at this point in the history
  • Loading branch information
poyoho committed Apr 20, 2022
1 parent 0b2d307 commit 1d468c8
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 10 deletions.
19 changes: 19 additions & 0 deletions packages/vite/src/node/__tests__/cleanString.spec.ts
Expand Up @@ -32,6 +32,25 @@ test('strings', () => {
expect(clean).toMatch('const b = "\0\0\0\0"')
})

test('escape character', () => {
const clean = emptyString(`
'1\\'1'
"1\\"1"
"1\\"1\\"1"
"1\\'1'\\"1"
"1'1'"
"1'\\'1\\''\\"1\\"\\""
'1"\\"1\\""\\"1\\"\\"'
'""1""'
'"""1"""'
'""""1""""'
"''1''"
"'''1'''"
"''''1''''"
`)
expect(clean).not.toMatch('1')
})

test('strings comment nested', () => {
expect(
emptyString(`
Expand Down
12 changes: 10 additions & 2 deletions packages/vite/src/node/cleanString.ts
Expand Up @@ -2,7 +2,8 @@ import type { RollupError } from 'rollup'
// bank on the non-overlapping nature of regex matches and combine all filters into one giant regex
// /`([^`\$\{\}]|\$\{(`|\g<1>)*\})*`/g can match nested string template
// but js not support match expression(\g<0>). so clean string template(`...`) in other ways.
const cleanerRE = /"[^"]*"|'[^']*'|\/\*(.|[\r\n])*?\*\/|\/\/.*/g
const cleanerRE =
/"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'|\/\*(.|[\r\n])*?\*\/|\/\/.*/g

const blankReplacer = (s: string) => ' '.repeat(s.length)
const stringBlankReplacer = (s: string) =>
Expand All @@ -25,9 +26,16 @@ export function emptyString(raw: string): string {
}

const enum LexerState {
// template string
inTemplateString,
inInterpolationExpression,
inObjectExpression
inObjectExpression,
// strings
inSingleQuoteString,
inDoubleQuoteString,
// comments
inMultilineCommentsRE,
inSinglelineCommentsRE
}

function replaceAt(
Expand Down
17 changes: 10 additions & 7 deletions packages/vite/src/node/plugins/css.ts
Expand Up @@ -1122,7 +1122,7 @@ export async function hoistAtRules(css: string) {
// to top when multiple files are concatenated.
// match until semicolon that's not in quotes
s.replace(
/@import\s*(?:url\([^\)]*\)|"[^"]*"|'[^']*'|[^;]*).*?;/gm,
/@import\s*(?:url\([^\)]*\)|"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'|[^;]*).*?;/gm,
(match) => {
s.appendLeft(0, match)
return ''
Expand All @@ -1131,13 +1131,16 @@ export async function hoistAtRules(css: string) {
// #6333
// CSS @charset must be the top-first in the file, hoist the first to top
let foundCharset = false
s.replace(/@charset\s*(?:"[^"]*"|'[^']*'|[^;]*).*?;/gm, (match) => {
if (!foundCharset) {
s.prepend(match)
foundCharset = true
s.replace(
/@charset\s*(?:"([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*'|[^;]*).*?;/gm,
(match) => {
if (!foundCharset) {
s.prepend(match)
foundCharset = true
}
return ''
}
return ''
})
)
return s.toString()
}

Expand Down
3 changes: 2 additions & 1 deletion packages/vite/src/node/plugins/html.ts
Expand Up @@ -46,7 +46,8 @@ interface ScriptAssetsUrl {
const htmlProxyRE = /\?html-proxy=?[&inline\-css]*&index=(\d+)\.(js|css)$/
const inlineCSSRE = /__VITE_INLINE_CSS__([^_]+_\d+)__/g
// Do not allow preceding '.', but do allow preceding '...' for spread operations
const inlineImportRE = /(?<!(?<!\.\.)\.)\bimport\s*\(("[^"]*"|'[^']*')\)/g
const inlineImportRE =
/(?<!(?<!\.\.)\.)\bimport\s*\(("([^"]|(?<=\\)")*"|'([^']|(?<=\\)')*')\)/g
const htmlLangRE = /\.(html|htm)$/

export const isHTMLProxy = (id: string): boolean => htmlProxyRE.test(id)
Expand Down

0 comments on commit 1d468c8

Please sign in to comment.