Skip to content

Commit 68dc4a0

Browse files
committed
deps: picomatch@4.0.4
(cherry picked from commit 150231d)
1 parent 1bb6703 commit 68dc4a0

5 files changed

Lines changed: 334 additions & 29 deletions

File tree

node_modules/tinyglobby/node_modules/picomatch/lib/constants.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
const WIN_SLASH = '\\\\/';
44
const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
55

6+
const DEFAULT_MAX_EXTGLOB_RECURSION = 0;
7+
68
/**
79
* Posix glob regex
810
*/
@@ -69,6 +71,7 @@ const WINDOWS_CHARS = {
6971
*/
7072

7173
const POSIX_REGEX_SOURCE = {
74+
__proto__: null,
7275
alnum: 'a-zA-Z0-9',
7376
alpha: 'a-zA-Z',
7477
ascii: '\\x00-\\x7F',
@@ -86,6 +89,7 @@ const POSIX_REGEX_SOURCE = {
8689
};
8790

8891
module.exports = {
92+
DEFAULT_MAX_EXTGLOB_RECURSION,
8993
MAX_LENGTH: 1024 * 64,
9094
POSIX_REGEX_SOURCE,
9195

node_modules/tinyglobby/node_modules/picomatch/lib/parse.js

Lines changed: 301 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,277 @@ const syntaxError = (type, char) => {
4545
return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
4646
};
4747

48+
const splitTopLevel = input => {
49+
const parts = [];
50+
let bracket = 0;
51+
let paren = 0;
52+
let quote = 0;
53+
let value = '';
54+
let escaped = false;
55+
56+
for (const ch of input) {
57+
if (escaped === true) {
58+
value += ch;
59+
escaped = false;
60+
continue;
61+
}
62+
63+
if (ch === '\\') {
64+
value += ch;
65+
escaped = true;
66+
continue;
67+
}
68+
69+
if (ch === '"') {
70+
quote = quote === 1 ? 0 : 1;
71+
value += ch;
72+
continue;
73+
}
74+
75+
if (quote === 0) {
76+
if (ch === '[') {
77+
bracket++;
78+
} else if (ch === ']' && bracket > 0) {
79+
bracket--;
80+
} else if (bracket === 0) {
81+
if (ch === '(') {
82+
paren++;
83+
} else if (ch === ')' && paren > 0) {
84+
paren--;
85+
} else if (ch === '|' && paren === 0) {
86+
parts.push(value);
87+
value = '';
88+
continue;
89+
}
90+
}
91+
}
92+
93+
value += ch;
94+
}
95+
96+
parts.push(value);
97+
return parts;
98+
};
99+
100+
const isPlainBranch = branch => {
101+
let escaped = false;
102+
103+
for (const ch of branch) {
104+
if (escaped === true) {
105+
escaped = false;
106+
continue;
107+
}
108+
109+
if (ch === '\\') {
110+
escaped = true;
111+
continue;
112+
}
113+
114+
if (/[?*+@!()[\]{}]/.test(ch)) {
115+
return false;
116+
}
117+
}
118+
119+
return true;
120+
};
121+
122+
const normalizeSimpleBranch = branch => {
123+
let value = branch.trim();
124+
let changed = true;
125+
126+
while (changed === true) {
127+
changed = false;
128+
129+
if (/^@\([^\\()[\]{}|]+\)$/.test(value)) {
130+
value = value.slice(2, -1);
131+
changed = true;
132+
}
133+
}
134+
135+
if (!isPlainBranch(value)) {
136+
return;
137+
}
138+
139+
return value.replace(/\\(.)/g, '$1');
140+
};
141+
142+
const hasRepeatedCharPrefixOverlap = branches => {
143+
const values = branches.map(normalizeSimpleBranch).filter(Boolean);
144+
145+
for (let i = 0; i < values.length; i++) {
146+
for (let j = i + 1; j < values.length; j++) {
147+
const a = values[i];
148+
const b = values[j];
149+
const char = a[0];
150+
151+
if (!char || a !== char.repeat(a.length) || b !== char.repeat(b.length)) {
152+
continue;
153+
}
154+
155+
if (a === b || a.startsWith(b) || b.startsWith(a)) {
156+
return true;
157+
}
158+
}
159+
}
160+
161+
return false;
162+
};
163+
164+
const parseRepeatedExtglob = (pattern, requireEnd = true) => {
165+
if ((pattern[0] !== '+' && pattern[0] !== '*') || pattern[1] !== '(') {
166+
return;
167+
}
168+
169+
let bracket = 0;
170+
let paren = 0;
171+
let quote = 0;
172+
let escaped = false;
173+
174+
for (let i = 1; i < pattern.length; i++) {
175+
const ch = pattern[i];
176+
177+
if (escaped === true) {
178+
escaped = false;
179+
continue;
180+
}
181+
182+
if (ch === '\\') {
183+
escaped = true;
184+
continue;
185+
}
186+
187+
if (ch === '"') {
188+
quote = quote === 1 ? 0 : 1;
189+
continue;
190+
}
191+
192+
if (quote === 1) {
193+
continue;
194+
}
195+
196+
if (ch === '[') {
197+
bracket++;
198+
continue;
199+
}
200+
201+
if (ch === ']' && bracket > 0) {
202+
bracket--;
203+
continue;
204+
}
205+
206+
if (bracket > 0) {
207+
continue;
208+
}
209+
210+
if (ch === '(') {
211+
paren++;
212+
continue;
213+
}
214+
215+
if (ch === ')') {
216+
paren--;
217+
218+
if (paren === 0) {
219+
if (requireEnd === true && i !== pattern.length - 1) {
220+
return;
221+
}
222+
223+
return {
224+
type: pattern[0],
225+
body: pattern.slice(2, i),
226+
end: i
227+
};
228+
}
229+
}
230+
}
231+
};
232+
233+
const getStarExtglobSequenceOutput = pattern => {
234+
let index = 0;
235+
const chars = [];
236+
237+
while (index < pattern.length) {
238+
const match = parseRepeatedExtglob(pattern.slice(index), false);
239+
240+
if (!match || match.type !== '*') {
241+
return;
242+
}
243+
244+
const branches = splitTopLevel(match.body).map(branch => branch.trim());
245+
if (branches.length !== 1) {
246+
return;
247+
}
248+
249+
const branch = normalizeSimpleBranch(branches[0]);
250+
if (!branch || branch.length !== 1) {
251+
return;
252+
}
253+
254+
chars.push(branch);
255+
index += match.end + 1;
256+
}
257+
258+
if (chars.length < 1) {
259+
return;
260+
}
261+
262+
const source = chars.length === 1
263+
? utils.escapeRegex(chars[0])
264+
: `[${chars.map(ch => utils.escapeRegex(ch)).join('')}]`;
265+
266+
return `${source}*`;
267+
};
268+
269+
const repeatedExtglobRecursion = pattern => {
270+
let depth = 0;
271+
let value = pattern.trim();
272+
let match = parseRepeatedExtglob(value);
273+
274+
while (match) {
275+
depth++;
276+
value = match.body.trim();
277+
match = parseRepeatedExtglob(value);
278+
}
279+
280+
return depth;
281+
};
282+
283+
const analyzeRepeatedExtglob = (body, options) => {
284+
if (options.maxExtglobRecursion === false) {
285+
return { risky: false };
286+
}
287+
288+
const max =
289+
typeof options.maxExtglobRecursion === 'number'
290+
? options.maxExtglobRecursion
291+
: constants.DEFAULT_MAX_EXTGLOB_RECURSION;
292+
293+
const branches = splitTopLevel(body).map(branch => branch.trim());
294+
295+
if (branches.length > 1) {
296+
if (
297+
branches.some(branch => branch === '') ||
298+
branches.some(branch => /^[*?]+$/.test(branch)) ||
299+
hasRepeatedCharPrefixOverlap(branches)
300+
) {
301+
return { risky: true };
302+
}
303+
}
304+
305+
for (const branch of branches) {
306+
const safeOutput = getStarExtglobSequenceOutput(branch);
307+
if (safeOutput) {
308+
return { risky: true, safeOutput };
309+
}
310+
311+
if (repeatedExtglobRecursion(branch) > max) {
312+
return { risky: true };
313+
}
314+
}
315+
316+
return { risky: false };
317+
};
318+
48319
/**
49320
* Parse the given input string.
50321
* @param {String} input
@@ -225,6 +496,8 @@ const parse = (input, options) => {
225496
token.prev = prev;
226497
token.parens = state.parens;
227498
token.output = state.output;
499+
token.startIndex = state.index;
500+
token.tokensIndex = tokens.length;
228501
const output = (opts.capture ? '(' : '') + token.open;
229502

230503
increment('parens');
@@ -234,6 +507,34 @@ const parse = (input, options) => {
234507
};
235508

236509
const extglobClose = token => {
510+
const literal = input.slice(token.startIndex, state.index + 1);
511+
const body = input.slice(token.startIndex + 2, state.index);
512+
const analysis = analyzeRepeatedExtglob(body, opts);
513+
514+
if ((token.type === 'plus' || token.type === 'star') && analysis.risky) {
515+
const safeOutput = analysis.safeOutput
516+
? (token.output ? '' : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput)
517+
: undefined;
518+
const open = tokens[token.tokensIndex];
519+
520+
open.type = 'text';
521+
open.value = literal;
522+
open.output = safeOutput || utils.escapeRegex(literal);
523+
524+
for (let i = token.tokensIndex + 1; i < tokens.length; i++) {
525+
tokens[i].value = '';
526+
tokens[i].output = '';
527+
delete tokens[i].suffix;
528+
}
529+
530+
state.output = token.output + open.output;
531+
state.backtrack = true;
532+
533+
push({ type: 'paren', extglob: true, value, output: '' });
534+
decrement('parens');
535+
return;
536+
}
537+
237538
let output = token.close + (opts.capture ? ')' : '');
238539
let rest;
239540

node_modules/tinyglobby/node_modules/picomatch/lib/picomatch.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,14 @@ picomatch.scan = (input, options) => scan(input, options);
233233
* Compile a regular expression from the `state` object returned by the
234234
* [parse()](#parse) method.
235235
*
236+
* ```js
237+
* const picomatch = require('picomatch');
238+
* const state = picomatch.parse('*.js');
239+
* // picomatch.compileRe(state[, options]);
240+
*
241+
* console.log(picomatch.compileRe(state));
242+
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
243+
* ```
236244
* @param {Object} `state`
237245
* @param {Object} `options`
238246
* @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.
@@ -268,10 +276,10 @@ picomatch.compileRe = (state, options, returnOutput = false, returnState = false
268276
*
269277
* ```js
270278
* const picomatch = require('picomatch');
271-
* const state = picomatch.parse('*.js');
272-
* // picomatch.compileRe(state[, options]);
279+
* // picomatch.makeRe(state[, options]);
273280
*
274-
* console.log(picomatch.compileRe(state));
281+
* const result = picomatch.makeRe('*.js');
282+
* console.log(result);
275283
* //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
276284
* ```
277285
* @param {String} `state` The object returned from the `.parse` method.

node_modules/tinyglobby/node_modules/picomatch/package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "picomatch",
33
"description": "Blazing fast and accurate glob matcher written in JavaScript, with no dependencies and full support for standard and extended Bash glob features, including braces, extglobs, POSIX brackets, and regular expressions.",
4-
"version": "4.0.3",
4+
"version": "4.0.4",
55
"homepage": "https://github.com/micromatch/picomatch",
66
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
77
"funding": "https://github.com/sponsors/jonschlinkert",
@@ -32,8 +32,7 @@
3232
"fill-range": "^7.0.1",
3333
"gulp-format-md": "^2.0.0",
3434
"mocha": "^10.4.0",
35-
"nyc": "^15.1.0",
36-
"time-require": "github:jonschlinkert/time-require"
35+
"nyc": "^15.1.0"
3736
},
3837
"keywords": [
3938
"glob",

0 commit comments

Comments
 (0)