bvaughn / bvaughn/react-highlight-words

Trying to match \b (word boundary) regex results in eternal loop and out-of-memory

Open
#42 2 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
JavaScript
Stars
2.3k
Forks
175
PR merge metrics
No merged PRs in 30d

Description

I am using Highlighter in a project where only the beginning of words should be hightlighted. The code is like this:
```js

```
If the `${this.inputToHighlight = ''` (empty string) so that searchWords evaluates to `\\b` then this results in an loop and eventally an time-out or out-of-memory.

Other than in this edge case, it works to match word boundaries this way. I worked around the issue for now by using
```js
searchWords={this.inputToHighlight ? [`\\b${this.inputToHighlight}`] : ['']}
```

Stack-Trace (from Firefox Console, but time-out also happens in Chrome and IE) is like:
```
The above error occurred in the component:
in Highlighter (at SearchInput.js:140)
in div (at SearchInput.js:138)
in div (created by Option)
in Option (created by Select)
in div (created by Select)
in div (created by Select)
in div (created by Select)
in Select (created by CreatableSelect)
in CreatableSelect (created by Async)
in Async (created by AsyncCreatableSelect)
in AsyncCreatableSelect (at SearchInput.js:181)
in form (at SearchInput.js:157)
in SearchInput (at SearchApp.js:31)
in div (at SearchApp.js:30)

Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
react-dom.development.js:9747
Error: Script terminated by timeout at:
findChunks/<@webpack-internal:///540:373:14
findChunks@webpack-internal:///540:360:12
findAll@webpack-internal:///540:302:17
Highlighter@webpack-internal:///540:137:18
mountIndeterminateComponent@webpack-internal:///498:8032:15
beginWork@webpack-internal:///498:8221:16
performUnitOfWork@webpack-internal:///498:10224:16
workLoop@webpack-internal:///498:10288:26
callCallback@webpack-internal:///498:542:9
invokeGuardedCallbackDev@webpack-internal:///498:581:7
invokeGuardedCallback@webpack-internal:///498:438:5
renderRoot@webpack-internal:///498:10366:7
performWorkOnRoot@webpack-internal:///498:11014:24
performWork@webpack-internal:///498:10967:7
batchedUpdates@webpack-internal:///498:11086:9
batchedUpdates@webpack-internal:///498:2330:12
dispatchEvent@webpack-internal:///498:3421:5
EventListener.handleEvent*listen@webpack-internal:///500:29:7
trapBubbledEvent@webpack-internal:///498:3381:10
listenTo@webpack-internal:///498:3744:9
ensureListeningTo@webpack-internal:///498:13717:3
setInitialProperties$1@webpack-internal:///498:13956:7
finalizeInitialChildren@webpack-internal:///498:14989:5
completeWork@webpack-internal:///498:8648:19
completeUnitOfWork@webpack-internal:///498:10132:18
performUnitOfWork@webpack-internal:///498:10234:14
workLoop@webpack-internal:///498:10288:26
callCallback@webpack-internal:///498:542:9
invokeGuardedCallbackDev@webpack-internal:///498:581:7
invokeGuardedCallback@webpack-internal:///498:438:5
renderRoot@webpack-internal:///498:10366:7
performWorkOnRoot@webpack-internal:///498:11014:24
performWork@webpack-internal:///498:10967:7
requestWork@webpack-internal:///498:10878:7
scheduleWorkImpl@webpack-internal:///498:10732:11
scheduleWork@webpack-internal:///498:10689:12
scheduleTopLevelUpdate@webpack-internal:///498:11193:5
updateContainer@webpack-internal:///498:11231:7
renderSubtreeIntoContainer/<@webpack-internal:///498:15226:7
unbatchedUpdates@webpack-internal:///498:11102:12
renderSubtreeIntoContainer@webpack-internal:///498:15225:5
render@webpack-internal:///498:15290:12
SearchApp@webpack-internal:///496:51:3
@webpack-internal:///452:41:19
mightThrow@webpack-internal:///7:3534:21
setTimeout handler*resolve/<@webpack-internal:///7:3640:9
fire@webpack-internal:///7:3268:11
fireWith@webpack-internal:///7:3398:7
fire@webpack-internal:///7:3406:5
fire@webpack-internal:///7:3268:11
fireWith@webpack-internal:///7:3398:7
ready@webpack-internal:///7:3878:3
completed@webpack-internal:///7:3888:2
EventListener.handleEvent*@webpack-internal:///7:3904:2
@webpack-internal:///7:28:4
@webpack-internal:///7:14:3
@http://localhost/js/app.bundle.js:113:1
__webpack_require__@http://localhost/js/app.bundle.js:20:12
@webpack-internal:///452:2:65
@http://localhost/js/app.bundle.js:2927:1
__webpack_require__@http://localhost/js/app.bundle.js:20:12
@http://localhost/js/app.bundle.js:1635:18
__webpack_require__@http://localhost/js/app.bundle.js:20:12
@http://localhost/js/app.bundle.js:63:18
@http://localhost/js/app.bundle.js:1:11
app.bundle.js%20line%203510%20%3E%20eval:373:14
Error: Should have found an error boundary. This error is likely caused by a bug in React. Please file an issue.
app.bundle.js%20line%20789%20%3E%20eval:42:15
invariant
invariant.js:42
renderRoot
react-dom.development.js:10392
performWorkOnRoot
react-dom.development.js:11014
performWork
react-dom.development.js:10967
batchedUpdates
react-dom.development.js:11086
batchedUpdates
react-dom.development.js:2330
dispatchEvent
react-dom.development.js:3421
dispatchEvent self-hosted:1035:17
```

I could setup something on glitch.com or codepen, but do not have much time at the moment, so hopefully this is enough to reproduce.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at the Highlighter component and the findChunks/findAll entries named in the stack trace. Reproduce with an empty input so searchWords evaluates to \\b, then compare it with the provided empty-string workaround. Done means the boundary case renders without timing out or exhausting memory while normal boundary matching still works.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.