diff --git a/lib/picomatch.js b/lib/picomatch.js index fbb8b1c..9ccbbb4 100644 --- a/lib/picomatch.js +++ b/lib/picomatch.js @@ -5,6 +5,7 @@ const parse = require('./parse'); const utils = require('./utils'); const constants = require('./constants'); const isObject = val => val && typeof val === 'object' && !Array.isArray(val); +const hasBracketTokens = state => Array.isArray(state.tokens) && state.tokens.some(token => token.type === 'bracket'); /** * Creates a matcher function from one or more glob patterns. The @@ -63,7 +64,7 @@ const picomatch = (glob, options, returnState = false) => { } const matcher = (input, returnObject = false) => { - const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); + const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix, state }); const result = { glob, state, regex, posix, input, output, match, isMatch }; if (typeof opts.onResult === 'function') { @@ -113,7 +114,7 @@ const picomatch = (glob, options, returnState = false) => { * @api public */ -picomatch.test = (input, regex, options, { glob, posix } = {}) => { +picomatch.test = (input, regex, options, { glob, posix, state } = {}) => { if (typeof input !== 'string') { throw new TypeError('Expected input to be a string'); } @@ -124,12 +125,13 @@ picomatch.test = (input, regex, options, { glob, posix } = {}) => { const opts = options || {}; const format = opts.format || (posix ? utils.toPosixSlashes : null); - let match = input === glob; + const literalMatch = opts.literalBrackets === true || !hasBracketTokens(state); + let match = literalMatch && input === glob; let output = (match && format) ? format(input) : input; if (match === false) { output = format ? format(input) : input; - match = output === glob; + match = literalMatch && output === glob; } if (match === false || opts.capture === true) { diff --git a/test/brackets.js b/test/brackets.js index c510625..208b039 100644 --- a/test/brackets.js +++ b/test/brackets.js @@ -4,6 +4,19 @@ const assert = require('assert'); const { isMatch } = require('..'); describe('brackets', () => { + describe('character classes', () => { + it('should not let exact string matching bypass character classes', () => { + assert(!isMatch('[1-5]', '[1-5]')); + assert(!isMatch('[1-5]', '[1-5]', { literalBrackets: false })); + assert(isMatch('3', '[1-5]')); + }); + + it('should still match literal brackets when requested', () => { + assert(isMatch('[1-5]', '\\[1-5\\]')); + assert(isMatch('[1-5]', '[1-5]', { literalBrackets: true })); + }); + }); + describe('trailing stars', () => { it('should support stars following brackets', () => { assert(isMatch('a', '[a]*'));