From e9417d9f7bdf292b46e7919081997f50002ce94c Mon Sep 17 00:00:00 2001 From: Aniket-Engg Date: Mon, 5 Jul 2021 14:29:56 +0530 Subject: [PATCH] handle npm imports for Slither --- libs/remixd/src/services/slitherClient.ts | 47 ++++++++++++++++++++--- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/libs/remixd/src/services/slitherClient.ts b/libs/remixd/src/services/slitherClient.ts index b4f54254ce..7221fb6d70 100644 --- a/libs/remixd/src/services/slitherClient.ts +++ b/libs/remixd/src/services/slitherClient.ts @@ -2,7 +2,7 @@ import * as WS from 'ws' // eslint-disable-line import { PluginClient } from '@remixproject/plugin' -import { existsSync, readFileSync } from 'fs' +import { existsSync, readFileSync, readdirSync } from 'fs' import { OutputStandard } from '../types' // eslint-disable-line const { spawn, execSync } = require('child_process') @@ -24,6 +24,31 @@ export class SlitherClient extends PluginClient { this.currentSharedFolder = currentSharedFolder } + mapNpmDepsDir (list) { + const remixNpmDepsPath = `${this.currentSharedFolder}/.deps/npm` + const localNpmDepsPath = `${this.currentSharedFolder}/node_modules` + const npmDepsExists = existsSync(remixNpmDepsPath) + const nodeModulesExists = existsSync(localNpmDepsPath) + let isLocalDep = false, isRemixDep = false + let allowPathString = '', remapString = '' + + for (const e of list) { + const importPath = e.replace(/import ['"]/g, '').trim() + const packageName = importPath.split('/')[0] + if (nodeModulesExists && readdirSync(localNpmDepsPath).includes(packageName)) { + isLocalDep = true + remapString+= `${packageName}=./node_modules/${packageName} ` + } else if (npmDepsExists && readdirSync(remixNpmDepsPath).includes(packageName)) { + isRemixDep = true + remapString+= `${packageName}=./.deps/npm/${packageName} ` + } + } + if (isLocalDep) allowPathString+= './node_modules,' + if (isRemixDep) allowPathString+= './.deps/npm,' + + return { remapString, allowPathString} +} + transform (detectors: Record[]): OutputStandard[] { const standardReport: OutputStandard[] = [] for (const e of detectors) { @@ -85,10 +110,22 @@ export class SlitherClient extends PluginClient { } else console.log('\x1b[32m%s\x1b[0m', '[Slither Analysis]: Compiler version is same as installed solc version') } const outputFile: string = 'remix-slitherReport_' + Date.now() + '.json' - const optimizeOption: string = optimize ? '--optimize ' : '' - const evmOption: string = evmVersion ? `--evm-version ${evmVersion}` : '' - const solcArgs: string = optimizeOption || evmOption ? `--solc-args '${optimizeOption}${evmOption}'` : '' - const cmd: string = `slither ${filePath} ${solcArgs} --json ${outputFile}` + const fileContent = readFileSync(`${this.currentSharedFolder}/${filePath}`, 'utf8') + const importsArr = fileContent.match(/import ['"][^.|..](.+?)['"];/g) + let allowPaths = '', remaps = '' + if(importsArr?.length) { + const { remapString, allowPathString} = this.mapNpmDepsDir(importsArr) + allowPaths = allowPathString + remaps = remapString.trim() + } + const allowPathsOption: string = allowPaths ? `--allow-paths ${allowPaths}` : '' + const optimizeOption: string = optimize ? ' --optimize ' : '' + const evmOption: string = evmVersion ? ` --evm-version ${evmVersion}` : '' + const solcArgs: string = optimizeOption || evmOption || allowPathsOption ? `--solc-args '${allowPathsOption}${optimizeOption}${evmOption}'` : '' + const solcRemaps = remaps ? `--solc-remaps "${remaps}"` : '' + + const cmd: string = `slither ${filePath} ${solcArgs} ${solcRemaps} --json ${outputFile}` + console.log('command--->', cmd) console.log('\x1b[32m%s\x1b[0m', '[Slither Analysis]: Running Slither...') const child = spawn(cmd, options) const response = {}