Socket
Socket
Sign inDemoInstall

solhint

Package Overview
Dependencies
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

solhint - npm Package Compare versions

Comparing version 4.0.0 to 4.1.1

lib/formatters/sarif.js

2

lib/common/ast-types.js
function isFallbackFunction(node) {
return isFunctionDefinition(node) && node.isFallback
return isFunctionDefinition(node) && (node.isFallback || node.isReceiveEther)
}

@@ -4,0 +4,0 @@

@@ -11,2 +11,3 @@ # Eslint formatters

- compact.js: eslint - Nicholas C. Zakas
- sarif.js: [@microsoft/eslint-formatter-sarif](https://www.npmjs.com/package/@microsoft/eslint-formatter-sarif)

@@ -44,3 +44,3 @@ const fs = require('fs')

const tokens = parser.tokenize(inputStr, { loc: true })
const tokens = parser.tokenize(inputStr, { loc: true, range: true })
const reporter = new Reporter(tokens, config)

@@ -47,0 +47,0 @@ const listener = new TreeListener(checkers(reporter, config, inputStr, tokens, fileName))

@@ -26,2 +26,7 @@ const BaseChecker = require('../base-checker')

},
notes: [
{
note: 'Solhint allows this rule to automatically fix the code with `--fix` option',
},
],
},

@@ -28,0 +33,0 @@

@@ -25,2 +25,7 @@ const BaseChecker = require('../base-checker')

},
notes: [
{
note: 'Solhint allows this rule to automatically fix the code with `--fix` option',
},
],
},

@@ -31,3 +36,3 @@

defaultSetup: 'warn',
fixable: true,
schema: null,

@@ -44,8 +49,25 @@ }

if (node.stateMutability !== 'payable') {
this.warn(node, 'When fallback is not payable you will not be able to receive ether')
this.warn(
node,
'Fallback should be external and payable to accept native currency',
this.fixStatement(node)
)
}
}
}
fixStatement(node) {
const range = node.range
const stringToPut = ' payable '
if (node.isReceiveEther) {
range[0] += 9
} else {
range[0] += 10
}
return (fixer) => fixer.insertTextBeforeRange(range, stringToPut)
}
}
module.exports = PayableFallbackChecker

@@ -64,3 +64,3 @@ const BaseChecker = require('../base-checker')

defaultSetup: [DEFAULT_SEVERITY, DEFAULT_QUOTES_TYPE],
fixable: true,
schema: {

@@ -117,7 +117,29 @@ type: 'string',

_error(ctx) {
this.error(ctx, `Use ${this.quoteType} quotes for string literals`)
_error(node) {
this.error(node, `Use ${this.quoteType} quotes for string literals`, this.fixStatement(node))
}
swapQuotes(inputString, quoteType) {
// Define the opposite quote type
const oppositeQuote = quoteType === "'" ? '"' : "'"
// Regular expression to match either single or double quotes within the string
const quoteRegex = new RegExp(`[${quoteType}${oppositeQuote}]`, 'g')
// Replace each occurrence of the specified quote type with the opposite quote
const resultString = inputString.replace(quoteRegex, (match) =>
match === quoteType ? oppositeQuote : quoteType
)
return resultString
}
fixStatement(node) {
const stringToPut = this.swapQuotes(node.value, this.incorrectQuote)
const range = node.range
range[1] -= 1
return (fixer) => fixer.replaceTextRange(range, stringToPut)
}
}
module.exports = QuotesChecker

@@ -9,4 +9,12 @@ const BaseChecker = require('../base-checker')

docs: {
description: 'Contract name must be in CamelCase.',
description: 'Contract, Structs and Enums should be in CamelCase.',
category: 'Style Guide Rules',
notes: [
{
note: 'Solhint allows this rule to automatically fix the code with `--fix` option',
},
{
note: 'The FIX will only change first letter and remove underscores',
},
],
},

@@ -17,3 +25,3 @@

defaultSetup: 'warn',
fixable: true,
schema: null,

@@ -28,24 +36,50 @@ }

ContractDefinition(node) {
this.validateName(node)
this.validateName(node, 'contract')
}
EnumDefinition(node) {
this.validateName(node)
this.validateName(node, 'enum')
}
StructDefinition(node) {
this.validateName(node)
this.validateName(node, 'struct')
}
validateName(node) {
validateName(node, type) {
if (naming.isNotCamelCase(node.name)) {
this._error(node)
this._error(node, type)
}
}
_error(node) {
this.error(node, 'Contract name must be in CamelCase')
fixStatement(node, type) {
// Remove leading and trailing underscores
let nameToPut = node.name.replace(/^[_]+|[_]+$/g, '')
// Replace '-' with space and split the string into an array
let words = nameToPut.replace(/-/g, ' ').split('_')
// Capitalize the first letter of each word
words = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
// Join the words back into a single string
nameToPut = words.join('')
const originalNameLength = node.name.length
const typeLength = type.length
const rangeStart = node.range[0] + typeLength + 1
const rangeEnd = node.range[0] + typeLength + originalNameLength
return (fixer) => fixer.replaceTextRange([rangeStart, rangeEnd], nameToPut)
}
_error(node, type) {
this.error(
node,
'Contract, Structs and Enums should be in CamelCase',
this.fixStatement(node, type)
)
}
}
module.exports = ContractNameCamelcaseChecker

@@ -11,2 +11,10 @@ const BaseChecker = require('../base-checker')

category: 'Style Guide Rules',
notes: [
{
note: 'Solhint allows this rule to automatically fix the code with `--fix` option',
},
{
note: 'The FIX will only change first letter and remove underscores',
},
],
},

@@ -17,3 +25,3 @@

defaultSetup: 'warn',
fixable: true,
schema: null,

@@ -27,5 +35,27 @@ }

fixStatement(node) {
// Remove leading and trailing underscores
let nameToPut = node.name.replace(/^[_]+|[_]+$/g, '')
// Replace '-' with space and split the string into an array
let words = nameToPut.replace(/-/g, ' ').split('_')
// Capitalize the first letter of each word
words = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
// Join the words back into a single string
nameToPut = words.join('')
const originalNameLength = node.name.length
const typeLength = 'event'.length
const rangeStart = node.range[0] + typeLength + 1
const rangeEnd = node.range[0] + typeLength + originalNameLength
return (fixer) => fixer.replaceTextRange([rangeStart, rangeEnd], nameToPut)
}
EventDefinition(node) {
if (naming.isNotCamelCase(node.name)) {
this.error(node, 'Event name must be in CamelCase')
this.error(node, 'Event name must be in CamelCase', this.fixStatement(node))
}

@@ -32,0 +62,0 @@ }

@@ -70,3 +70,3 @@ const BaseChecker = require('../base-checker')

{
note: 'This rule considers functions and variables in Libraries as well',
note: 'This rule DO NOT considers functions and variables in Libraries',
},

@@ -82,2 +82,5 @@ {

},
{
note: 'Solhint allows this rule to automatically fix the code with `--fix` option',
},
],

@@ -108,22 +111,23 @@ },

// ContractDefinition(node) {
// if (node.kind === 'library') {
// this.inLibrary = true
// }
// }
ContractDefinition(node) {
if (node.kind === 'library') {
this.inLibrary = true
}
}
// 'ContractDefinition:exit'() {
// this.inLibrary = false
// }
'ContractDefinition:exit'() {
this.inLibrary = false
}
FunctionDefinition(node) {
if (!node.name) {
return
if (!this.inLibrary) {
if (!node.name) {
return
}
const isPrivate = node.visibility === 'private'
const isInternal = node.visibility === 'internal' || node.visibility === 'default'
const shouldHaveLeadingUnderscore = isPrivate || isInternal
this.validateName(node, shouldHaveLeadingUnderscore, 'function')
}
const isPrivate = node.visibility === 'private'
const isInternal = node.visibility === 'internal' || node.visibility === 'default'
// const shouldHaveLeadingUnderscore = isPrivate || (!this.inLibrary && isInternal)
const shouldHaveLeadingUnderscore = isPrivate || isInternal
this.validateName(node, shouldHaveLeadingUnderscore, 'function')
}

@@ -140,14 +144,16 @@

VariableDeclaration(node) {
if (!this.inStateVariableDeclaration) {
// if strict is enabled, non-state vars should not start with leading underscore
if (this.isStrict) {
this.validateName(node, false, 'variable')
if (!this.inLibrary) {
if (!this.inStateVariableDeclaration) {
// if strict is enabled, non-state vars should not start with leading underscore
if (this.isStrict) {
this.validateName(node, false, 'variable')
}
return
}
return
const isPrivate = node.visibility === 'private'
const isInternal = node.visibility === 'internal' || node.visibility === 'default'
const shouldHaveLeadingUnderscore = isPrivate || isInternal
this.validateName(node, shouldHaveLeadingUnderscore, 'variable')
}
const isPrivate = node.visibility === 'private'
const isInternal = node.visibility === 'internal' || node.visibility === 'default'
const shouldHaveLeadingUnderscore = isPrivate || isInternal
this.validateName(node, shouldHaveLeadingUnderscore, 'variable')
}

@@ -154,0 +160,0 @@

@@ -15,3 +15,3 @@ const BaseChecker = require('../base-checker')

defaultSetup: 'warn',
fixable: true,
schema: null,

@@ -25,9 +25,23 @@ }

Identifier(node) {
if (node.name === 'suicide') {
this.error(node, 'Use "selfdestruct" instead of deprecated "suicide"')
FunctionCall(node) {
if (node.expression.type === 'Identifier' && node.expression.name === 'suicide') {
this.error(
node,
'Use "selfdestruct" instead of deprecated "suicide"',
this.fixStatement(node)
)
}
}
fixStatement(node) {
let stringToPut = 'selfdestruct()'
if (node.arguments.length > 0) {
stringToPut = 'selfdestruct(' + node.arguments[0].name + ')'
}
return (fixer) => fixer.replaceTextRange(node.range, stringToPut)
}
}
module.exports = AvoidSuicideChecker
{
"name": "solhint",
"version": "4.0.0",
"version": "4.1.1",
"description": "Solidity Code Linter",

@@ -21,3 +21,3 @@ "main": "lib/index.js",

"test:coverage": "npm run exec-tests",
"test": "mocha --recursive",
"test": "mocha --recursive --timeout 10000",
"lint": "eslint .",

@@ -24,0 +24,0 @@ "generate-rulesets": "node scripts/generate-rulesets.js && prettier --write conf/rulesets",

<p align="center">
<img src="solhint.png">
<a href="https://protofire.io/projects/solhint" target="_blank"><img src="solhint.png"></a>
</p>
<p align="center">
By <a href="https://protofire.io/">Protofire</a>
By <a href="https://protofire.io/" target="_blank">Protofire</a>
</p>
[![Join Discord](https://img.shields.io/badge/join-Discord-red)](https://discord.gg/4TYGq3zpjs)
[![](https://img.shields.io/badge/Solhint%20Website-cyan)](https://protofire.io/projects/solhint)
[![](https://img.shields.io/badge/Join%20Our%20Discord-magenta)](https://discord.gg/4TYGq3zpjs)
[![Donate with Ethereum](https://img.shields.io/badge/Donate-ETH-blue)](https://etherscan.io/address/0xA81705c8C247C413a19A244938ae7f4A0393944e)

@@ -17,4 +18,6 @@ [![NPM version](https://badge.fury.io/js/solhint.svg)](https://npmjs.org/package/solhint)

provides both **Security** and **Style Guide** validations.
<br>
[VISIT OUR WEBSITE](https://protofire.io/projects/solhint)<br>
[JOIN OUR DISCORD SERVER](https://discord.gg/4TYGq3zpjs)
<br>
## Installation

@@ -61,3 +64,3 @@

-V, --version output the version number
-f, --formatter [name] report formatter name (stylish, table, tap, unix, json, compact)
-f, --formatter [name] report formatter name (stylish, table, tap, unix, json, compact, sarif)
-w, --max-warnings [maxWarningsNumber] number of allowed warnings

@@ -203,4 +206,7 @@ -c, --config [file_name] file to use as your .solhint.json

## Docker
### Solhint has an official Docker Image
Go to docker folder and follow [this](docker/docker.md) instructions.
## Documentation
Related documentation you may find [here](https://protofire.github.io/solhint/).

@@ -207,0 +213,0 @@

@@ -24,3 +24,3 @@ #!/usr/bin/env node

'-f, --formatter [name]',
'report formatter name (stylish, table, tap, unix, json, compact)'
'report formatter name (stylish, table, tap, unix, json, compact, sarif)'
)

@@ -131,3 +131,2 @@ .option('-w, --max-warnings [maxWarningsNumber]', 'number of allowed warnings')

// if (program.opts().fix || program.opts().fixShow) {
if (program.opts().fix) {

@@ -145,8 +144,2 @@ for (const report of reports) {

if (fixed) {
// // skip or not the report when fixed
// // This was filtering fixed rules so status code was not 1
// if (program.opts().fix) {
// report.reports = report.reports.filter((x) => !x.fix)
// } else {
// console.log('report.reports :>> ', report.reports)
report.reports.forEach((report) => {

@@ -157,8 +150,4 @@ if (report.fix !== null) {

})
// }
// fs.writeFileSync(report.filePath, output)
try {
fs.writeFileSync(report.filePath, output)
// fs.writeFileSync('no-console/Foo1Modified.sol', output)
} catch (error) {

@@ -165,0 +154,0 @@ console.error('An error occurred while writing the file:', error)

@@ -36,2 +36,13 @@ const { assertNoWarnings, assertErrorMessage, assertWarnsCount } = require('../../common/asserts')

})
it('should raise for other fallback types when are not payable', () => {
const code = contractWith('fallback() external {} receive() onlyOwner {}')
const report = linter.processStr(code, {
rules: { 'payable-fallback': 'warn' },
})
assertWarnsCount(report, 2)
assertErrorMessage(report, 'payable')
})
})

@@ -57,2 +57,3 @@ const assert = require('assert')

"assembly { linkerSymbol('uint') }",
"assembly { let hexString := '48656c6c6f2c2027576f726c64212722' }",
]

@@ -59,0 +60,0 @@

@@ -14,5 +14,2 @@ const assert = require('assert')

contractWith('function foo() internal {}'),
libraryWith('function foo() {}'),
libraryWith('function foo() private {}'),
libraryWith('function foo() internal {}'),

@@ -24,4 +21,2 @@ // warn when public/external names start with _

contractWith('function _foo() external {}'),
libraryWith('function _foo() public {}'),
libraryWith('function _foo() external {}'),
]

@@ -33,4 +28,2 @@

contractWith('function foo() public returns (uint256 _bar) {}'),
libraryWith('function _foo() returns (uint256 _bar) {}'),
libraryWith('function _foo(uint _bar) private {}'),
]

@@ -37,0 +30,0 @@

const assert = require('assert')
const linter = require('../../../lib/index')
const funcWith = require('../../common/contract-builder').funcWith
const contractWith = require('../../common/contract-builder').contractWith

@@ -21,3 +22,3 @@ describe('Linter - avoid-suicide', () => {

const ALMOST_DEPRECATION_ERRORS = ['suicides();']
const ALMOST_DEPRECATION_ERRORS = ['suicides();', 'selfdestruct();']

@@ -35,2 +36,12 @@ ALMOST_DEPRECATION_ERRORS.forEach((curText) =>

)
it(`should not return error when doing for struct name suicide`, () => {
const code = contractWith('struct AnotherNiceStruct { uint256 suicide; uint256 c; }')
const report = linter.processStr(code, {
rules: { 'avoid-suicide': 'error' },
})
assert.equal(report.errorCount, 0)
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc