mirror of https://github.com/actions/toolkit
Prevent accidental file matching when glob contains trailing slash (#805)
* Draft Solution * Update internal-globber.ts * Cleanup * Fix Test * Cleanuppull/809/head
parent
b33912b7cc
commit
98549fbf21
|
@ -97,6 +97,24 @@ describe('globber', () => {
|
|||
])
|
||||
})
|
||||
|
||||
it('does not match file with trailing slash when implicitDescendants=true', async () => {
|
||||
// Create the following layout:
|
||||
// <root>
|
||||
// <root>/file
|
||||
const root = path.join(
|
||||
getTestTemp(),
|
||||
'defaults-to-implicit-descendants-true'
|
||||
)
|
||||
|
||||
const filePath = path.join(root, 'file')
|
||||
|
||||
await fs.mkdir(root, {recursive: true})
|
||||
await fs.writeFile(filePath, 'test file content')
|
||||
|
||||
const itemPaths = await glob(`${filePath}/`, {})
|
||||
expect(itemPaths).toEqual([])
|
||||
})
|
||||
|
||||
it('defaults to omitBrokenSymbolicLinks=true', async () => {
|
||||
// Create the following layout:
|
||||
// <root>
|
||||
|
|
|
@ -26,7 +26,7 @@ describe('pattern', () => {
|
|||
it('escapes homedir', async () => {
|
||||
const home = path.join(getTestTemp(), 'home-with-[and]')
|
||||
await fs.mkdir(home, {recursive: true})
|
||||
const pattern = new Pattern('~/m*', undefined, home)
|
||||
const pattern = new Pattern('~/m*', false, undefined, home)
|
||||
|
||||
expect(pattern.searchPath).toBe(home)
|
||||
expect(pattern.match(path.join(home, 'match'))).toBeTruthy()
|
||||
|
|
|
@ -66,7 +66,6 @@ export class DefaultGlobber implements Globber {
|
|||
async *globGenerator(): AsyncGenerator<string, void> {
|
||||
// Fill in defaults options
|
||||
const options = globOptionsHelper.getOptions(this.options)
|
||||
|
||||
// Implicit descendants?
|
||||
const patterns: Pattern[] = []
|
||||
for (const pattern of this.patterns) {
|
||||
|
@ -77,12 +76,13 @@ export class DefaultGlobber implements Globber {
|
|||
pattern.segments[pattern.segments.length - 1] !== '**')
|
||||
) {
|
||||
patterns.push(
|
||||
new Pattern(pattern.negate, pattern.segments.concat('**'))
|
||||
new Pattern(pattern.negate, true, pattern.segments.concat('**'))
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Push the search paths
|
||||
|
||||
const stack: SearchState[] = []
|
||||
for (const searchPath of patternHelper.getSearchPaths(patterns)) {
|
||||
core.debug(`Search path '${searchPath}'`)
|
||||
|
@ -180,6 +180,7 @@ export class DefaultGlobber implements Globber {
|
|||
}
|
||||
|
||||
result.searchPaths.push(...patternHelper.getSearchPaths(result.patterns))
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
|
|
|
@ -43,15 +43,31 @@ export class Pattern {
|
|||
*/
|
||||
private readonly rootRegExp: RegExp
|
||||
|
||||
/**
|
||||
* Indicates that the pattern is implicitly added as opposed to user specified.
|
||||
*/
|
||||
private readonly isImplicitPattern: boolean
|
||||
|
||||
/* eslint-disable no-dupe-class-members */
|
||||
// Disable no-dupe-class-members due to false positive for method overload
|
||||
// https://github.com/typescript-eslint/typescript-eslint/issues/291
|
||||
|
||||
constructor(pattern: string)
|
||||
constructor(pattern: string, segments: undefined, homedir: string)
|
||||
constructor(negate: boolean, segments: string[])
|
||||
constructor(
|
||||
pattern: string,
|
||||
isImplicitPattern: boolean,
|
||||
segments: undefined,
|
||||
homedir: string
|
||||
)
|
||||
constructor(
|
||||
negate: boolean,
|
||||
isImplicitPattern: boolean,
|
||||
segments: string[],
|
||||
homedir?: string
|
||||
)
|
||||
constructor(
|
||||
patternOrNegate: string | boolean,
|
||||
isImplicitPattern: boolean = false,
|
||||
segments?: string[],
|
||||
homedir?: string
|
||||
) {
|
||||
|
@ -107,6 +123,8 @@ export class Pattern {
|
|||
IS_WINDOWS ? 'i' : ''
|
||||
)
|
||||
|
||||
this.isImplicitPattern = isImplicitPattern
|
||||
|
||||
// Create minimatch
|
||||
const minimatchOptions: IMinimatchOptions = {
|
||||
dot: true,
|
||||
|
@ -132,7 +150,7 @@ export class Pattern {
|
|||
// Append a trailing slash. Otherwise Minimatch will not match the directory immediately
|
||||
// preceding the globstar. For example, given the pattern `/foo/**`, Minimatch returns
|
||||
// false for `/foo` but returns true for `/foo/`. Append a trailing slash to handle that quirk.
|
||||
if (!itemPath.endsWith(path.sep)) {
|
||||
if (!itemPath.endsWith(path.sep) && this.isImplicitPattern === false) {
|
||||
// Note, this is safe because the constructor ensures the pattern has an absolute root.
|
||||
// For example, formats like C: and C:foo on Windows are resolved to an absolute root.
|
||||
itemPath = `${itemPath}${path.sep}`
|
||||
|
|
Loading…
Reference in New Issue