repl: runtime deprecate instantiating without new

PR-URL: https://github.com/nodejs/node/pull/54869
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: LiviaMedeiros <livia@cirno.name>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
This commit is contained in:
Aviv Keller 2024-11-07 03:03:05 -05:00 committed by GitHub
parent f38cefa04b
commit 0368f2f662
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 32 additions and 9 deletions

View File

@ -3748,6 +3748,9 @@ It is recommended to use the `new` qualifier instead. This applies to all Zlib c
<!-- YAML <!-- YAML
changes: changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/54869
description: Runtime deprecation.
- version: - version:
- v22.9.0 - v22.9.0
- v20.18.0 - v20.18.0
@ -3755,7 +3758,7 @@ changes:
description: Documentation-only deprecation. description: Documentation-only deprecation.
--> -->
Type: Documentation-only Type: Runtime
Instantiating classes without the `new` qualifier exported by the `node:repl` module is deprecated. Instantiating classes without the `new` qualifier exported by the `node:repl` module is deprecated.
It is recommended to use the `new` qualifier instead. This applies to all REPL classes, including It is recommended to use the `new` qualifier instead. This applies to all REPL classes, including

View File

@ -63,6 +63,7 @@ const {
} = internalBinding('util'); } = internalBinding('util');
const { isNativeError, isPromise } = internalBinding('types'); const { isNativeError, isPromise } = internalBinding('types');
const { getOptionValue } = require('internal/options'); const { getOptionValue } = require('internal/options');
const assert = require('internal/assert');
const { encodings } = internalBinding('string_decoder'); const { encodings } = internalBinding('string_decoder');
const noCrypto = !process.versions.openssl; const noCrypto = !process.versions.openssl;
@ -179,6 +180,14 @@ function deprecate(fn, msg, code, useEmitSync) {
return deprecated; return deprecated;
} }
function deprecateInstantiation(target, code, ...args) {
assert(typeof code === 'string');
getDeprecationWarningEmitter(code, `Instantiating ${target.name} without the 'new' keyword has been deprecated.`, target)();
return ReflectConstruct(target, args);
}
function decorateErrorStack(err) { function decorateErrorStack(err) {
if (!(isError(err) && err.stack) || err[decorated_private_symbol]) if (!(isError(err) && err.stack) || err[decorated_private_symbol])
return; return;
@ -879,6 +888,7 @@ module.exports = {
defineLazyProperties, defineLazyProperties,
defineReplaceableLazyAttribute, defineReplaceableLazyAttribute,
deprecate, deprecate,
deprecateInstantiation,
emitExperimentalWarning, emitExperimentalWarning,
encodingsMap, encodingsMap,
exposeInterface, exposeInterface,

View File

@ -111,6 +111,7 @@ const {
decorateErrorStack, decorateErrorStack,
isError, isError,
deprecate, deprecate,
deprecateInstantiation,
SideEffectFreeRegExpPrototypeSymbolReplace, SideEffectFreeRegExpPrototypeSymbolReplace,
SideEffectFreeRegExpPrototypeSymbolSplit, SideEffectFreeRegExpPrototypeSymbolSplit,
} = require('internal/util'); } = require('internal/util');
@ -262,12 +263,7 @@ function REPLServer(prompt,
ignoreUndefined, ignoreUndefined,
replMode) { replMode) {
if (!(this instanceof REPLServer)) { if (!(this instanceof REPLServer)) {
return new REPLServer(prompt, return deprecateInstantiation(REPLServer, 'DEP0185', prompt, stream, eval_, useGlobal, ignoreUndefined, replMode);
stream,
eval_,
useGlobal,
ignoreUndefined,
replMode);
} }
let options; let options;

View File

@ -65,7 +65,7 @@ function runAndWait(cmds, repl) {
return promise; return promise;
} }
const repl = REPLServer({ const repl = new REPLServer({
prompt: PROMPT, prompt: PROMPT,
stream: new REPLStream(), stream: new REPLStream(),
ignoreUndefined: true, ignoreUndefined: true,

View File

@ -57,7 +57,7 @@ function runAndWait(cmds, repl) {
} }
async function tests(options) { async function tests(options) {
const repl = REPLServer({ const repl = new REPLServer({
prompt: PROMPT, prompt: PROMPT,
stream: new REPLStream(), stream: new REPLStream(),
ignoreUndefined: true, ignoreUndefined: true,

View File

@ -1035,3 +1035,17 @@ function event(ee, expected) {
})); }));
}); });
} }
{
const server = repl.REPLServer();
common.expectWarning({
DeprecationWarning: {
DEP0185: 'Instantiating REPLServer without the \'new\' keyword has been deprecated.',
// For the 'url.format' test-case.
DEP0169:
'`url.parse()` behavior is not standardized and prone to errors that have security implications. ' +
'Use the WHATWG URL API instead. CVEs are not issued for `url.parse()` vulnerabilities.',
}
});
server.emit('line', '.exit');
}