Update safe-string-coercion to handle additions of string literals (#25286)

* Update safe-string-coercion to handle additions of string literals

Adding strings shouldn't trigger a lint violation of this rule, since
adding strings are always safe.
This commit is contained in:
lauren 2022-10-04 12:29:36 -07:00 committed by GitHub
parent aed33a49cc
commit af9afe9b3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 8 deletions

View File

@ -11,6 +11,15 @@
const rule = require('../safe-string-coercion');
const {RuleTester} = require('eslint');
RuleTester.setDefaultConfig({
parser: require.resolve('babel-eslint'),
parserOptions: {
ecmaVersion: 6,
sourceType: 'module',
},
});
const ruleTester = new RuleTester();
const missingDevCheckMessage =
@ -87,6 +96,9 @@ ruleTester.run('eslint-rules/safe-string-coercion', rule, {
// doesn't violate this rule.
"if (typeof obj === 'string') { if (typeof obj === 'string' && obj.length) {} else {'' + obj} }",
"if (typeof obj === 'string') if (typeof obj === 'string' && obj.length) {} else {'' + obj}",
"'' + ''",
"'' + '' + ''",
"`test${foo}` + ''",
],
invalid: [
{
@ -261,5 +273,16 @@ ruleTester.run('eslint-rules/safe-string-coercion', rule, {
},
],
},
{
code: `'' + obj + ''`,
errors: [
{message: missingDevCheckMessage + '\n' + message},
{message: missingDevCheckMessage + '\n' + message},
],
},
{
code: `foo\`text\` + ""`,
errors: [{message: missingDevCheckMessage + '\n' + message}],
},
],
});

View File

@ -17,6 +17,15 @@ function isEmptyLiteral(node) {
);
}
function isStringLiteral(node) {
return (
// TaggedTemplateExpressions can return non-strings
(node.type === 'TemplateLiteral' &&
node.parent.type !== 'TaggedTemplateExpression') ||
(node.type === 'Literal' && typeof node.value === 'string')
);
}
// Symbols and Temporal.* objects will throw when using `'' + value`, but that
// pattern can be faster than `String(value)` because JS engines can optimize
// `+` better in some cases. Therefore, in perf-sensitive production codepaths
@ -259,7 +268,24 @@ function hasCoercionCheck(node) {
}
}
function plusEmptyString(context, node) {
function isOnlyAddingStrings(node) {
if (node.operator !== '+') {
return;
}
if (isStringLiteral(node.left) && isStringLiteral(node.right)) {
// It's always safe to add string literals
return true;
}
if (node.left.type === 'BinaryExpression' && isStringLiteral(node.right)) {
return isOnlyAddingStrings(node.left);
}
}
function checkBinaryExpression(context, node) {
if (isOnlyAddingStrings(node)) {
return;
}
if (
node.operator === '+' &&
(isEmptyLiteral(node.left) || isEmptyLiteral(node.right))
@ -337,7 +363,7 @@ module.exports = {
},
create(context) {
return {
BinaryExpression: node => plusEmptyString(context, node),
BinaryExpression: node => checkBinaryExpression(context, node),
CallExpression: node => coerceWithStringConstructor(context, node),
};
},