Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

lavamoat-tofu

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

lavamoat-tofu - npm Package Compare versions

Comparing version 2.0.10 to 3.1.0

test/inspectImports.js

7

package.json
{
"name": "lavamoat-tofu",
"version": "2.0.10",
"version": "3.1.0",
"main": "src/index.js",
"license": "MIT",
"dependencies": {
"acorn-globals": "^4.3.3"
"acorn-globals": "^6.0.0",
"acorn-walk": "^7.1.1"
},

@@ -31,3 +32,3 @@ "devDependencies": {

"homepage": "https://github.com/LavaMoat/lavamoat#readme",
"gitHead": "c0ddda67f0fb21117ee203cc0c5bd00db832b006"
"gitHead": "676f77b5cfecb655f58a272f2871b10abbf3c618"
}

@@ -1,7 +0,10 @@

const inspectSource = require('./inspectSource')
const { parse } = require('acorn-globals')
const { inspectGlobals, inspectImports } = require('./inspectSource')
const utils = require('./util')
module.exports = {
inspectSource,
utils
inspectGlobals,
inspectImports,
utils,
parse
}
const acornGlobals = require('acorn-globals')
const walk = require('acorn-walk')
const standardJsGlobals = require('./standardGlobals.js')

@@ -6,3 +7,3 @@

getMemberExpressionNesting,
getKeysForMemberExpressionChain,
getPathFromMemberExpressionChain,
reduceToTopmostApiCalls,

@@ -12,5 +13,5 @@ addGlobalUsage

module.exports = inspectSource
module.exports = { inspectGlobals, inspectImports }
function inspectSource (source, {
function inspectGlobals (source, {
ignoredRefs = [],

@@ -20,3 +21,3 @@ globalRefs = [],

} = {}) {
const ast = acornGlobals.parse(source)
const ast = (typeof source === 'object') ? source : acornGlobals.parse(source)
const detectedGlobals = acornGlobals(ast)

@@ -66,61 +67,6 @@

function inspectPatternElementForPaths (child) {
if (child.type === 'ObjectPattern') {
return inspectObjectPatternForPaths(child)
} else if (child.type === 'ArrayPattern') {
return inspectArrayPatternForPaths(child)
} else if (child.type === 'Identifier') {
// return a single empty element, meaning "one result, the whole thing"
return [[]]
} else {
throw new Error(`LavaMoat/tofu - inspectPatternElementForPaths - unable to parse element "${child.type}"`)
}
}
function inspectObjectPatternForPaths (node) {
// if it has computed props or a RestElement, we cant meaningfully pursue any deeper
// so return a single empty path, meaning "one result, the whole thing"
const expansionForbidden = node.properties.some(prop => prop.computed || prop.type === 'RestElement')
if (expansionForbidden) return [[]]
// expand each property into a path, recursively
let paths = []
node.properties.forEach(prop => {
const propName = prop.key.name
const child = prop.value
paths = paths.concat(
inspectPatternElementForPaths(child)
.map(partial => [propName, ...partial])
)
})
return paths
}
function inspectArrayPatternForPaths (node) {
// if it has a RestElement, we cant meaningfully pursue any deeper
// so return a single empty path, meaning "one result, the whole thing"
const expansionForbidden = node.elements.some(el => el.type === 'RestElement')
if (expansionForbidden) return [[]]
// expand each property into a path, recursively
let paths = []
node.elements.forEach((child, propName) => {
paths = paths.concat(
inspectPatternElementForPaths(child)
.map(partial => [propName, ...partial])
)
})
return paths
}
function inspectIdentifierForDirectMembershipChain (variableName, identifierNode) {
let identifierUse = 'read'
const memberExpressions = getMemberExpressionNesting(identifierNode)
const hasMembershipChain = Boolean(memberExpressions.length)
const { memberExpressions, parentOfMembershipChain, topmostMember } = getMemberExpressionNesting(identifierNode)
// determine if used in an assignment expression
const topmostMember = hasMembershipChain ? memberExpressions[0] : identifierNode
const topmostMemberIndex = identifierNode.parents.indexOf(topmostMember)
if (topmostMemberIndex < 1) {
throw Error('unnexpected value for memberTopIndex')
}
const topmostMemberParentIndex = topmostMemberIndex - 1
const parentOfMembershipChain = identifierNode.parents[topmostMemberParentIndex]
const isAssignment = parentOfMembershipChain.type === 'AssignmentExpression'

@@ -133,7 +79,7 @@ const isAssignmentTarget = parentOfMembershipChain.left === topmostMember

// if not used in any member expressions AND is not a global ref, expose as is
if (!hasMembershipChain) {
if (!memberExpressions.length) {
return { identifierUse, path: [variableName], parent: parentOfMembershipChain }
}
const memberKeys = getKeysForMemberExpressionChain(memberExpressions)
return { identifierUse, path: memberKeys, parent: parentOfMembershipChain }
const path = [variableName, ...getPathFromMemberExpressionChain(memberExpressions)]
return { identifierUse, path, parent: parentOfMembershipChain }
}

@@ -150,1 +96,79 @@

}
function inspectImports (source) {
const ast = (typeof source === 'object') ? source : acornGlobals.parse(source)
let cjsImports = []
walk.ancestor(ast, {
CallExpression: function (node, parents) {
const { callee, arguments: [moduleNameNode] } = node
if (callee.type !== 'Identifier') return
if (callee.name !== 'require') return
if (moduleNameNode.type !== 'Literal') return
const moduleName = moduleNameNode.value
// inspect for members
node.parents = parents
const { memberExpressions, parentOfMembershipChain } = getMemberExpressionNesting(node)
const initialPath = [moduleName, ...getPathFromMemberExpressionChain(memberExpressions)]
// exit early if unrecognized parent
if (parentOfMembershipChain.type !== 'VariableDeclarator') {
// not sure when this is would be hit?
cjsImports.push(initialPath)
return
}
// inspect for destructuring
cjsImports = cjsImports.concat(
inspectPatternElementForPaths(parentOfMembershipChain.id)
.map(partial => [...initialPath, ...partial])
)
}
})
const cjsImportStrings = cjsImports.map(item => item.join('.'))
return { cjsImports: cjsImportStrings }
}
function inspectPatternElementForPaths (child) {
if (child.type === 'ObjectPattern') {
return inspectObjectPatternForPaths(child)
} else if (child.type === 'ArrayPattern') {
return inspectArrayPatternForPaths(child)
} else if (child.type === 'Identifier') {
// return a single empty element, meaning "one result, the whole thing"
return [[]]
} else {
throw new Error(`LavaMoat/tofu - inspectPatternElementForPaths - unable to parse element "${child.type}"`)
}
}
function inspectObjectPatternForPaths (node) {
// if it has computed props or a RestElement, we cant meaningfully pursue any deeper
// so return a single empty path, meaning "one result, the whole thing"
const expansionForbidden = node.properties.some(prop => prop.computed || prop.type === 'RestElement')
if (expansionForbidden) return [[]]
// expand each property into a path, recursively
let paths = []
node.properties.forEach(prop => {
const propName = prop.key.name
const child = prop.value
paths = paths.concat(
inspectPatternElementForPaths(child)
.map(partial => [propName, ...partial])
)
})
return paths
}
function inspectArrayPatternForPaths (node) {
// if it has a RestElement, we cant meaningfully pursue any deeper
// so return a single empty path, meaning "one result, the whole thing"
const expansionForbidden = node.elements.some(el => el.type === 'RestElement')
if (expansionForbidden) return [[]]
// expand each property into a path, recursively
let paths = []
node.elements.forEach((child, propName) => {
paths = paths.concat(
inspectPatternElementForPaths(child)
.map(partial => [propName, ...partial])
)
})
return paths
}
module.exports = {
getMemberExpressionNesting,
getKeysForMemberExpressionChain,
getPathFromMemberExpressionChain,
isDirectMemberExpression,

@@ -20,10 +20,16 @@ isUndefinedCheck,

const memberExpressions = getTailmostMatchingChain(parents, isDirectMemberExpression).reverse()
return memberExpressions
// find parent of membership chain
const hasMembershipChain = Boolean(memberExpressions.length)
const topmostMember = hasMembershipChain ? memberExpressions[0] : identifierNode
const topmostMemberIndex = identifierNode.parents.indexOf(topmostMember)
if (topmostMemberIndex < 1) {
throw Error('unnexpected value for memberTopIndex')
}
const topmostMemberParentIndex = topmostMemberIndex - 1
const parentOfMembershipChain = identifierNode.parents[topmostMemberParentIndex]
return { memberExpressions, parentOfMembershipChain, topmostMember }
}
function getKeysForMemberExpressionChain (memberExpressions) {
function getPathFromMemberExpressionChain (memberExpressions) {
const keys = memberExpressions.map(member => getNameFromNode(member.property))
const rootMemberExpression = memberExpressions[0]
const rootName = getNameFromNode(rootMemberExpression.object)
keys.unshift(rootName)
return keys

@@ -30,0 +36,0 @@ }

require('./inspectSource')
require('./inspectImports')
require('./util')
const test = require('tape')
const deepEqual = require('deep-equal')
const { inspectSource } = require('../src/index')
const { inspectGlobals } = require('../src/index')

@@ -244,3 +244,3 @@

const src = fnToCodeBlock(fn)
const result = inspectSource(src, opts)
const result = inspectGlobals(src, opts)
const resultSorted = [...result.entries()].sort(sortBy(0))

@@ -247,0 +247,0 @@ const expectedSorted = Object.entries(expectedResultObj).sort(sortBy(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