Skip to content

fix: improve dynamic member access fallback and dataflow continuity#113

Open
Ris-1kd wants to merge 45 commits intoantgroup:mainfrom
Ris-1kd:main
Open

fix: improve dynamic member access fallback and dataflow continuity#113
Ris-1kd wants to merge 45 commits intoantgroup:mainfrom
Ris-1kd:main

Conversation

@Ris-1kd
Copy link
Copy Markdown
Collaborator

@Ris-1kd Ris-1kd commented Apr 1, 2026

No description provided.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request enhances the Python analyzer's taint tracking and symbol resolution capabilities. Key changes include the addition of a new taint flow rule for SQL injection, improved support for list comprehensions through append semantics and small union iteration, and the implementation of fallback mechanisms for unresolved member calls and ORM-style object managers. The review feedback highlights opportunities to optimize receiver evaluation, improve the performance of global method searches, and increase the efficiency of list index calculations.

return undefined
}

const receiver = this.processInstruction(scope, node.callee.object, state)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The receiver object node.callee.object has already been evaluated during the processing of node.callee (which calls processMemberAccess). Re-evaluating it here is redundant and could lead to incorrect analysis if the receiver expression has side effects (e.g., a function call). It is safer and more efficient to retrieve the already evaluated receiver from currentFclos.object if available.

Suggested change
const receiver = this.processInstruction(scope, node.callee.object, state)
const receiver = currentFclos?.object || this.processInstruction(scope, node.callee.object, state)

Comment on lines +407 to +422
for (const modKey of Object.keys(modules)) {
const modScope = modules[modKey]
for (const key of Object.keys(modScope?.value || {})) {
const cls = modScope.value[key]
if (cls?.vtype !== 'class') continue
const method = cls?.value?.[prop.name]
if (method?.vtype === 'fclos') {
const methodCopy = _.clone(method)
methodCopy._this = receiver
methodCopy.parent = receiver
methodCopy.object = receiver
methodCopy._qid = `${receiver?.qid || receiver?.sid || key}.${prop.name}`
return methodCopy
}
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This global search for a method across all classes in all modules is computationally expensive. Since this fallback is triggered for unresolved member calls, it could significantly degrade performance in large projects. Consider implementing a global method index or caching the results of this search to improve efficiency.

Comment on lines +901 to +904
const numericIndices = Object.keys(container.value)
.filter((k) => /^\d+$/.test(k))
.map((k) => Number(k))
const nextIndex = numericIndices.length > 0 ? Math.max(...numericIndices) + 1 : 0
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Calculating the next numeric index by filtering all keys and finding the maximum value on every push operation results in $O(N^2)$ complexity for list constructions (like list comprehensions). A more efficient approach would be to maintain a length property on the container or use Object.keys(container.value).length if the container is known to be a sequential list without holes.

Suggested change
const numericIndices = Object.keys(container.value)
.filter((k) => /^\d+$/.test(k))
.map((k) => Number(k))
const nextIndex = numericIndices.length > 0 ? Math.max(...numericIndices) + 1 : 0
const nextIndex = Object.keys(container.value).length

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant