From 0beb3d77e61e745689169c6e69cf502104096939 Mon Sep 17 00:00:00 2001 From: Yarchik Date: Tue, 23 Jun 2026 02:59:31 +0100 Subject: [PATCH] fix: escape multi-character separators before building the cleanup regex A multi-character `separator` (a documented string option) was concatenated straight into a `RegExp`, escaping only its first character: getSlug('foo bar baz', { separator: '..' }) // "foo" (bar, baz dropped) getSlug('foo bar baz', { separator: '++' }) // threw "Invalid regular expression" getSlug('foo bar baz', { separator: '()' }) // threw "Invalid regular expression" For '..' the second dot became an unescaped wildcard that swallowed the rest of the string (data loss); for '++'/'()' the result was an invalid pattern that threw. Escape the whole separator with the existing `escapeChars` helper and group it so the full sequence is matched when collapsing duplicates and trimming the ends. Single-character separators are unaffected. --- lib/speakingurl.js | 6 ++++-- test/test-separator.js | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/speakingurl.js b/lib/speakingurl.js index 4a62bc0..f2feea6 100644 --- a/lib/speakingurl.js +++ b/lib/speakingurl.js @@ -1605,9 +1605,11 @@ // eliminate duplicate separators // add separator // trim separators from start and end + var escapedSeparator = escapeChars(separator); + result = result.replace(/\s+/g, separator) - .replace(new RegExp('\\' + separator + '+', 'g'), separator) - .replace(new RegExp('(^\\' + separator + '+|\\' + separator + '+$)', 'g'), ''); + .replace(new RegExp('(?:' + escapedSeparator + ')+', 'g'), separator) + .replace(new RegExp('^(?:' + escapedSeparator + ')+|(?:' + escapedSeparator + ')+$', 'g'), ''); if (truncate && result.length > truncate) { lucky = result.charAt(truncate) === separator; diff --git a/test/test-separator.js b/test/test-separator.js index 62d78b6..387b5f6 100644 --- a/test/test-separator.js +++ b/test/test-separator.js @@ -35,6 +35,27 @@ describe('getSlug separator', function () { }); + it('should separate with a multi-character separator', function (done) { + + getSlug('Foo Bar Baz', { + separator: '..' + }) + .should.eql('foo..bar..baz'); + + getSlug('Foo Bar Baz', { + separator: '++' + }) + .should.eql('foo++bar++baz'); + + getSlug('Foo Bar Baz', { + separator: '()' + }) + .should.eql('foo()bar()baz'); + + done(); + + }); + it('should separate with non-whitespace, with trailing spaces', function (done) { getSlug(' Foo Bar Baz ', {