Skip to content

Commit

Permalink
fix: enclose regexp when using PCRE (#566)
Browse files Browse the repository at this point in the history
  • Loading branch information
eduardoboucas authored Jan 19, 2024
1 parent fd07443 commit 1057a31
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 23 deletions.
12 changes: 6 additions & 6 deletions node/declaration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,23 +163,23 @@ test('netlify.toml-defined excludedPath are respected', () => {
test('Does not escape front slashes in a regex pattern if they are already escaped', () => {
const regexPattern = '^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/shows(?:\\/(.*))(.json)?[\\/#\\?]?$'
const expected = '^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/shows(?:\\/(.*))(.json)?[\\/#\\?]?$'
const actual = parsePattern(regexPattern)

expect(actual).toEqual(expected)
expect(parsePattern(regexPattern, false)).toEqual(expected)
expect(parsePattern(regexPattern, true)).toEqual(expected)
})

test('Escapes front slashes in a regex pattern', () => {
const regexPattern = '^(?:/(_next/data/[^/]{1,}))?(?:/([^/.]{1,}))/shows(?:/(.*))(.json)?[/#\\?]?$'
const expected = '^(?:\\/(_next\\/data\\/[^/]{1,}))?(?:\\/([^/.]{1,}))\\/shows(?:\\/(.*))(.json)?[/#\\?]?$'
const actual = parsePattern(regexPattern)

expect(actual).toEqual(expected)
expect(parsePattern(regexPattern, false)).toEqual(expected)
expect(parsePattern(regexPattern, true)).toEqual(expected)
})

test('Ensures pattern match on the whole path', () => {
const regexPattern = '/foo/.*/bar'
const expected = '^\\/foo\\/.*\\/bar$'
const actual = parsePattern(regexPattern)

expect(actual).toEqual(expected)
expect(parsePattern(regexPattern, false)).toEqual(expected)
expect(parsePattern(regexPattern, true)).toEqual(expected)
})
33 changes: 26 additions & 7 deletions node/declaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,34 @@ const createDeclarationsFromFunctionConfigs = (
return declarations
}

// Validates and normalizes a pattern so that it's a valid regular expression
// in Go, which is the engine used by our edge nodes.
export const parsePattern = (pattern: string) => {
/**
* Normalizes a regular expression, ensuring it has a leading `^` and trailing
* `$` characters. It also converts the regular expression from PCRE to RE2 if
* needed.
*/
export const parsePattern = (pattern: string, pcreRegexpEngine: boolean) => {
let enclosedPattern = pattern
if (!pattern.startsWith('^')) enclosedPattern = `^${enclosedPattern}`
if (!pattern.endsWith('$')) enclosedPattern = `${enclosedPattern}$`

if (!pattern.startsWith('^')) {
enclosedPattern = `^${enclosedPattern}`
}

if (!pattern.endsWith('$')) {
enclosedPattern = `${enclosedPattern}$`
}

const regexp = new RegExp(enclosedPattern)
const regexpString = pcreRegexpEngine ? regexp.toString() : transformPCRERegexp(regexp)

// Strip leading and forward slashes.
return regexpString.slice(1, -1)
}

/**
* Transforms a PCRE regular expression into a RE2 expression, compatible
* with the Go engine used in our edge nodes.
*/
const transformPCRERegexp = (regexp: RegExp) => {
const newRegexp = regexpAST.transform(regexp, {
Assertion(path) {
// Lookaheads are not supported. If we find one, throw an error.
Expand All @@ -146,6 +166,5 @@ export const parsePattern = (pattern: string) => {
},
})

// Strip leading and forward slashes.
return newRegexp.toString().slice(1, -1)
return newRegexp.toString()
}
12 changes: 2 additions & 10 deletions node/manifest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,8 @@ const pathToRegularExpression = (path: string) => {

const getRegularExpression = (declaration: Declaration, pcreRegexpEngine: boolean) => {
if ('pattern' in declaration) {
if (pcreRegexpEngine) {
return declaration.pattern
}

try {
return parsePattern(declaration.pattern)
return parsePattern(declaration.pattern, pcreRegexpEngine)
} catch (error: unknown) {
throw wrapBundleError(
new Error(
Expand All @@ -252,13 +248,9 @@ const getExcludedRegularExpressions = (declaration: Declaration, pcreRegexpEngin
? declaration.excludedPattern
: [declaration.excludedPattern]

if (pcreRegexpEngine) {
return excludedPatterns
}

return excludedPatterns.map((excludedPattern) => {
try {
return parsePattern(excludedPattern)
return parsePattern(excludedPattern, pcreRegexpEngine)
} catch (error: unknown) {
throw wrapBundleError(
new Error(
Expand Down

0 comments on commit 1057a31

Please sign in to comment.