Skip to content

Directory exclude pattern improperly excludes directories with names that start the same #3007

Closed
@SteveTalbot

Description

@SteveTalbot

This issue affects version 3.5.5 and is very closely related to #1920

The problem

Imagine I want to exclude files in bin directories:

<exclude-pattern>*/bin/*</exclude-pattern>

This rule will also match and exclude any directory starting with bin, such as ./src/BingSearch/

The problem appears to be in the same area of code that caused #1920, specifically Filter.php#L221:

                if (substr($pattern, -2) === '/*') {
                    // Need to check this pattern for dirs as well as individual file paths.
                    $this->ignoreFilePatterns[$pattern] = $type;

                    $pattern = substr($pattern, 0, -2);
                    $this->ignoreDirPatterns[$pattern] = $type;
                } else {
                    // This is a file-specific pattern, so only need to check this
                    // for individual file paths.
                    $this->ignoreFilePatterns[$pattern] = $type;
                }

Removing the trailing slash with substr allows the pattern to match the directory, but it also allows it to match any directory with a name that starts the same.

Proposed solution

A simple fix is to anchor the directory pattern to the end of the string, like this:

                    $pattern = substr($pattern, 0, -2) . '$';
                    $this->ignoreDirPatterns[$pattern] = $type;

Or use a lookahead:

                    $pattern = substr($pattern, 0, -2) . '(?=/|$)';
                    $this->ignoreDirPatterns[$pattern] = $type;

Workaround

To exclude files in bin directories, use a lookahead in the exclude pattern in phpcs.xml:

<exclude-pattern>*/bin(?=/|$)/*</exclude-pattern>

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions