You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A dynamic namespace registered with a RegExp that carries the global (g) or
sticky (y) flag rejects connections intermittently.
Server.of and the parent-namespace matcher call .test() on the user supplied
regex as if it were a stateless predicate. Per the ECMAScript spec, RegExp.prototype.test() advances lastIndex when the regex has the g or y
flag and resumes from it on the next call, so a shared regex object returns
alternating results across connections.
Concretely, io.of(/^\/room-\d+$/g) connects /room-1, then rejects /room-2
with connect_error: "Invalid namespace", then connects /room-3, and so on:
The pattern is correct; only the leftover lastIndex state causes the rejection.
The fix resets lastIndex to 0 immediately before each .test() at both call
sites. It is a no-op for regexes without the g or y flag, so existing
behavior is unchanged.
Fair question. I am not deliberately setting a global flag on a namespace regex; the value here is defensive. Server.of accepts whatever RegExp the caller passes, and if that object carries g or y (a shared or reused regex, one produced by a helper or config, or a copy-pasted literal), .test() advances its lastIndex and the namespace then matches only every other connection. That is a silent, order-dependent failure that is hard to trace back to the flag. Resetting lastIndex before matching keeps the result independent of flags the caller did not intend to affect namespace routing. If you would rather guard against it another way (for example rejecting global/sticky regexes at registration), I can adjust.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A dynamic namespace registered with a
RegExpthat carries the global (g) orsticky (
y) flag rejects connections intermittently.Server.ofand the parent-namespace matcher call.test()on the user suppliedregex as if it were a stateless predicate. Per the ECMAScript spec,
RegExp.prototype.test()advanceslastIndexwhen the regex has thegoryflag and resumes from it on the next call, so a shared regex object returns
alternating results across connections.
Concretely,
io.of(/^\/room-\d+$/g)connects/room-1, then rejects/room-2with
connect_error: "Invalid namespace", then connects/room-3, and so on:The pattern is correct; only the leftover
lastIndexstate causes the rejection.The fix resets
lastIndexto 0 immediately before each.test()at both callsites. It is a no-op for regexes without the
goryflag, so existingbehavior is unchanged.