util: fix error's namespaced node_modules highlighting using inspect · nodejs/node@b68e0d1
@@ -250,7 +250,6 @@ const keyStrRegExp = /^[a-zA-Z_][a-zA-Z_0-9]*$/;
250250const numberRegExp = /^(0|[1-9][0-9]*)$/;
251251252252const coreModuleRegExp = /^ {4}at (?:[^/\\(]+ \(|)node:(.+):\d+:\d+\)?$/;
253-const nodeModulesRegExp = /[/\\]node_modules[/\\](.+?)(?=[/\\])/g;
254253255254const classRegExp = /^(\s+[^(]*?)\s*{/;
256255// eslint-disable-next-line node-core/no-unescaped-regexp-dot
@@ -1423,16 +1422,45 @@ function removeDuplicateErrorKeys(ctx, keys, err, stack) {
1423142214241423function markNodeModules(ctx, line) {
14251424let tempLine = '';
1426-let nodeModule;
1427-let pos = 0;
1428-while ((nodeModule = nodeModulesRegExp.exec(line)) !== null) {
1429-// '/node_modules/'.length === 14
1430-tempLine += StringPrototypeSlice(line, pos, nodeModule.index + 14);
1431-tempLine += ctx.stylize(nodeModule[1], 'module');
1432-pos = nodeModule.index + nodeModule[0].length;
1433-}
1434-if (pos !== 0) {
1435-line = tempLine + StringPrototypeSlice(line, pos);
1425+let lastPos = 0;
1426+let searchFrom = 0;
1427+1428+while (true) {
1429+const nodeModulePosition = StringPrototypeIndexOf(line, 'node_modules', searchFrom);
1430+if (nodeModulePosition === -1) {
1431+break;
1432+}
1433+1434+// Ensure it's a path segment: must have a path separator before and after
1435+const separator = line[nodeModulePosition - 1];
1436+const after = line[nodeModulePosition + 12]; // 'node_modules'.length === 12
1437+1438+if ((after !== '/' && after !== '\\') || (separator !== '/' && separator !== '\\')) {
1439+// Not a proper segment; continue searching
1440+searchFrom = nodeModulePosition + 1;
1441+continue;
1442+}
1443+1444+const moduleStart = nodeModulePosition + 13; // Include trailing separator
1445+1446+// Append up to and including '/node_modules/'
1447+tempLine += StringPrototypeSlice(line, lastPos, moduleStart);
1448+1449+let moduleEnd = StringPrototypeIndexOf(line, separator, moduleStart);
1450+if (line[moduleStart] === '@') {
1451+// Namespaced modules have an extra slash: @namespace/package
1452+moduleEnd = StringPrototypeIndexOf(line, separator, moduleEnd + 1);
1453+}
1454+1455+const nodeModule = StringPrototypeSlice(line, moduleStart, moduleEnd);
1456+tempLine += ctx.stylize(nodeModule, 'module');
1457+1458+lastPos = moduleEnd;
1459+searchFrom = moduleEnd;
1460+}
1461+1462+if (lastPos !== 0) {
1463+line = tempLine + StringPrototypeSlice(line, lastPos);
14361464}
14371465return line;
14381466}