#6274·lodash

[Bug]`_.truncate` hangs forever with a zero-length-capable regex `separator`

Author: waydeshiCreated Aug 11, 2026Updated Sep 15, 2026

Description

_.truncate(string, { separator }) enters an infinite loop when separator is a regex that can match the empty string at a non-zero offset (e.g. /(?<=,)\s*/). The inner exec loop never advances separator.lastIndex, so a zero-length match makes exec return the same match forever. One CPU core pins at 100% and the call never returns.

This is not a security issue (already triaged as out of scope: the separator is application-chosen, and every documented separator is safe). It is a correctness bug in the isRegExp(separator) branch.

Steps to reproduce

javascript
const _ = require('lodash');
_.truncate('a,b' + 'X'.repeat(200), { length: 30, separator: /(?<=,)\s*/ });
// never returns

Expected

Returns a truncated string in bounded time, as it does for string and ordinary regex separators.

Actual

Infinite loop; the process hangs at 100% CPU.

Root cause

lodash.js, truncate, the isRegExp(separator) branch:

javascript
separator.lastIndex = 0;
while ((match = separator.exec(substring))) {
  var newEnd = match.index;   // lastIndex is never advanced
}

For a zero-length match, match.index === separator.lastIndex and lastIndex stays fixed, so exec returns the identical match on every iteration.

Recommended fix

Advance lastIndex past zero-length matches inside the loop:

javascript
separator.lastIndex = 0;
while ((match = separator.exec(substring))) {
  var newEnd = match.index;
  if (match[0].length === 0) {
    separator.lastIndex++;
  }
}

Environment

  • lodash 4.18.1
  • Node.js, any recent version