-
Notifications
You must be signed in to change notification settings - Fork 30k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
repl: no RegExp side effects for static properties #18937
Conversation
7ac3414
to
53a63a8
Compare
Preserve all RegExp static properties - RegExp.$1 to RegExp.9 - input, lastMatch, lastParen - leftContext and rightContext Fixes: nodejs#18931
53a63a8
to
bc3f376
Compare
Just food for thought but a simpler solution would be to use RegExp from a different context: const RE = vm.runInNewContext('RegExp');
// ...
if (RE('pattern').test(input)) {
// ...
}
// RegExp.$_, RegExp.$_, etc. unaltered here. |
@bnoordhuis Yes, I thought about it! but we can't use global context ( |
@princejwesley |
@bnoordhuis User input from terminal to REPL eval call, we may have many regex calls - for instance emit key functions has to handle varies terminal character combinations with regular expression. if we try to fix side effect from REPL when the We can create new context and use it inside repl.js but we can't do the same for the whole code execution path (I mean from user key stroke to run code in vm). Am I wrong? BTW, why do we need Also whatever we do to avoid side effects is only applicable when |
why don't we set |
@princejwesley Sorry, missed your replies.
We could if all of core switched over to the new technique. You could start with repl.js, readline.js and tty.js. Cache the result of
It caused ecosystem fallout last time we tried that, IIRC. |
@bnoordhuis // Cache global and contextual RegExp binding
const regExpInstances = {
global: RegExp,
current: vm.runInNewContext('RegExp', vm.createContext())
};
...
try {
const scriptOptions = {
displayErrors: false,
breakOnSigint: self.breakEvalOnSigint
};
if (self.useGlobal) {
global.RegExp = regExps.context; // switch
result = script.runInThisContext(scriptOptions);
} else {
result = script.runInContext(context, scriptOptions);
}
} finally {
if (self.useGlobal) {
global.RegExp = regExps.global; // reset
}
... its not working for regex literal! :( |
That's too much of a hack. Too many ways it can go wrong. |
@bnoordhuis are you fine with landing this as is? As I see it, it will already improve the current situation, no matter that the solution is not elegant. |
Update: Update: |
I am unsure how to move forward here. Any further recommendations / notes from anyone? @bnoordhuis would you be fine with landing it as is or do you definitely want this to be reworked? |
|
I'll start with repl.js, tty.js and readline.js and update the PR. |
@@ -440,7 +440,7 @@ const errorTests = [ | |||
}, | |||
// Regression test for https://github.com/nodejs/node/issues/597 | |||
{ | |||
send: '/(.)(.)(.)(.)(.)(.)(.)(.)(.)/.test(\'123456789\')\n', | |||
send: '/(.)(.)(.)(.)(.)(.)(.)(.)(.)/.test(\'123456789abc\')\n', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps add a new block instead of changing this one?
Related to #18795 (comment). |
closing this PR. |
Preserve all RegExp static properties
Fixes: #18931
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
repl
cc: @bnoordhuis