no-new-buffer.js 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. 'use strict';
  2. const {getStaticValue} = require('@eslint-community/eslint-utils');
  3. const {newExpressionSelector} = require('./selectors/index.js');
  4. const {switchNewExpressionToCallExpression} = require('./fix/index.js');
  5. const isNumber = require('./utils/is-number.js');
  6. const ERROR = 'error';
  7. const ERROR_UNKNOWN = 'error-unknown';
  8. const SUGGESTION = 'suggestion';
  9. const messages = {
  10. [ERROR]: '`new Buffer()` is deprecated, use `Buffer.{{method}}()` instead.',
  11. [ERROR_UNKNOWN]: '`new Buffer()` is deprecated, use `Buffer.alloc()` or `Buffer.from()` instead.',
  12. [SUGGESTION]: 'Switch to `Buffer.{{replacement}}()`.',
  13. };
  14. const inferMethod = (bufferArguments, scope) => {
  15. if (bufferArguments.length !== 1) {
  16. return 'from';
  17. }
  18. const [firstArgument] = bufferArguments;
  19. if (firstArgument.type === 'SpreadElement') {
  20. return;
  21. }
  22. if (firstArgument.type === 'ArrayExpression' || firstArgument.type === 'TemplateLiteral') {
  23. return 'from';
  24. }
  25. if (isNumber(firstArgument, scope)) {
  26. return 'alloc';
  27. }
  28. const staticResult = getStaticValue(firstArgument, scope);
  29. if (staticResult) {
  30. const {value} = staticResult;
  31. if (
  32. typeof value === 'string'
  33. || Array.isArray(value)
  34. ) {
  35. return 'from';
  36. }
  37. }
  38. };
  39. function fix(node, sourceCode, method) {
  40. return function * (fixer) {
  41. yield fixer.insertTextAfter(node.callee, `.${method}`);
  42. yield * switchNewExpressionToCallExpression(node, sourceCode, fixer);
  43. };
  44. }
  45. /** @param {import('eslint').Rule.RuleContext} context */
  46. const create = context => {
  47. const sourceCode = context.getSourceCode();
  48. return {
  49. [newExpressionSelector('Buffer')](node) {
  50. const method = inferMethod(node.arguments, context.getScope());
  51. if (method) {
  52. return {
  53. node,
  54. messageId: ERROR,
  55. data: {method},
  56. fix: fix(node, sourceCode, method),
  57. };
  58. }
  59. return {
  60. node,
  61. messageId: ERROR_UNKNOWN,
  62. suggest: ['from', 'alloc'].map(replacement => ({
  63. messageId: SUGGESTION,
  64. data: {replacement},
  65. fix: fix(node, sourceCode, replacement),
  66. })),
  67. };
  68. },
  69. };
  70. };
  71. /** @type {import('eslint').Rule.RuleModule} */
  72. module.exports = {
  73. create,
  74. meta: {
  75. type: 'problem',
  76. docs: {
  77. description: 'Enforce the use of `Buffer.from()` and `Buffer.alloc()` instead of the deprecated `new Buffer()`.',
  78. },
  79. fixable: 'code',
  80. hasSuggestions: true,
  81. messages,
  82. },
  83. };