Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d2d6bf0

Browse files
committed
fix inefficient .enable() regex and .enabled() test
1 parent bc60914 commit d2d6bf0

File tree

3 files changed

+63
-39
lines changed

3 files changed

+63
-39
lines changed

package.json

+5
Original file line numberDiff line numberDiff line change
@@ -56,5 +56,10 @@
5656
"browser": "./src/browser.js",
5757
"engines": {
5858
"node": ">=6.0"
59+
},
60+
"xo": {
61+
"rules": {
62+
"import/extensions": "off"
63+
}
5964
}
6065
}

src/browser.js

+1
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ function useColors() {
129129

130130
// Is webkit? http://stackoverflow.com/a/16459606/376773
131131
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
132+
// eslint-disable-next-line no-return-assign
132133
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
133134
// Is firebug? http://stackoverflow.com/a/398120/376773
134135
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||

src/common.js

+57-39
Original file line numberDiff line numberDiff line change
@@ -166,24 +166,62 @@ function setup(env) {
166166
createDebug.names = [];
167167
createDebug.skips = [];
168168

169-
let i;
170-
const split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/);
171-
const len = split.length;
172-
173-
for (i = 0; i < len; i++) {
174-
if (!split[i]) {
175-
// ignore empty strings
176-
continue;
169+
const split = (typeof namespaces === 'string' ? namespaces : '')
170+
.trim()
171+
.replace(' ', ',')
172+
.split(',')
173+
.filter(Boolean);
174+
175+
for (const ns of split) {
176+
if (ns[0] === '-') {
177+
createDebug.skips.push(ns.slice(1));
178+
} else {
179+
createDebug.names.push(ns);
177180
}
181+
}
182+
}
178183

179-
namespaces = split[i].replace(/\*/g, '.*?');
180-
181-
if (namespaces[0] === '-') {
182-
createDebug.skips.push(new RegExp('^' + namespaces.slice(1) + '$'));
184+
/**
185+
* Checks if the given string matches a namespace template, honoring
186+
* asterisks as wildcards.
187+
*
188+
* @param {String} search
189+
* @param {String} template
190+
* @return {Boolean}
191+
*/
192+
function matchesTemplate(search, template) {
193+
let searchIndex = 0;
194+
let templateIndex = 0;
195+
let starIndex = -1;
196+
let matchIndex = 0;
197+
198+
while (searchIndex < search.length) {
199+
if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {
200+
// Match character or proceed with wildcard
201+
if (template[templateIndex] === '*') {
202+
starIndex = templateIndex;
203+
matchIndex = searchIndex;
204+
templateIndex++; // Skip the '*'
205+
} else {
206+
searchIndex++;
207+
templateIndex++;
208+
}
209+
} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition
210+
// Backtrack to the last '*' and try to match more characters
211+
templateIndex = starIndex + 1;
212+
matchIndex++;
213+
searchIndex = matchIndex;
183214
} else {
184-
createDebug.names.push(new RegExp('^' + namespaces + '$'));
215+
return false; // No match
185216
}
186217
}
218+
219+
// Handle trailing '*' in template
220+
while (templateIndex < template.length && template[templateIndex] === '*') {
221+
templateIndex++;
222+
}
223+
224+
return templateIndex === template.length;
187225
}
188226

189227
/**
@@ -194,8 +232,8 @@ function setup(env) {
194232
*/
195233
function disable() {
196234
const namespaces = [
197-
...createDebug.names.map(toNamespace),
198-
...createDebug.skips.map(toNamespace).map(namespace => '-' + namespace)
235+
...createDebug.names,
236+
...createDebug.skips.map(namespace => '-' + namespace)
199237
].join(',');
200238
createDebug.enable('');
201239
return namespaces;
@@ -209,41 +247,21 @@ function setup(env) {
209247
* @api public
210248
*/
211249
function enabled(name) {
212-
if (name[name.length - 1] === '*') {
213-
return true;
214-
}
215-
216-
let i;
217-
let len;
218-
219-
for (i = 0, len = createDebug.skips.length; i < len; i++) {
220-
if (createDebug.skips[i].test(name)) {
250+
for (const skip of createDebug.skips) {
251+
if (matchesTemplate(name, skip)) {
221252
return false;
222253
}
223254
}
224255

225-
for (i = 0, len = createDebug.names.length; i < len; i++) {
226-
if (createDebug.names[i].test(name)) {
256+
for (const ns of createDebug.names) {
257+
if (matchesTemplate(name, ns)) {
227258
return true;
228259
}
229260
}
230261

231262
return false;
232263
}
233264

234-
/**
235-
* Convert regexp to namespace
236-
*
237-
* @param {RegExp} regxep
238-
* @return {String} namespace
239-
* @api private
240-
*/
241-
function toNamespace(regexp) {
242-
return regexp.toString()
243-
.substring(2, regexp.toString().length - 2)
244-
.replace(/\.\*\?$/, '*');
245-
}
246-
247265
/**
248266
* Coerce `val`.
249267
*

0 commit comments

Comments
 (0)