Skip to content

Commit

Permalink
fix(python): update analyzer for import statements (#1592)
Browse files Browse the repository at this point in the history
* fix(python): update analyzer forimport statements

* feat(python): add test for internal statement
  • Loading branch information
elsapet committed May 14, 2024
1 parent 9e0660d commit 7ecf89c
Show file tree
Hide file tree
Showing 6 changed files with 460 additions and 1 deletion.
338 changes: 338 additions & 0 deletions internal/languages/python/.snapshots/TestImport--import.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,338 @@
high:
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 2
full_filename: import.py
filename: import.py
source:
location:
start: 2
end: 2
column:
start: 1
end: 17
sink:
location:
start: 2
end: 2
column:
start: 1
end: 17
content: ""
parent_line_number: 2
fingerprint: 55db11cd18d0af4114644d01cefbc79d_0
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_0
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 5
full_filename: import.py
filename: import.py
source:
location:
start: 5
end: 5
column:
start: 1
end: 18
sink:
location:
start: 5
end: 5
column:
start: 1
end: 18
content: ""
parent_line_number: 5
fingerprint: 55db11cd18d0af4114644d01cefbc79d_1
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_1
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 8
full_filename: import.py
filename: import.py
source:
location:
start: 8
end: 8
column:
start: 1
end: 15
sink:
location:
start: 8
end: 8
column:
start: 1
end: 15
content: ""
parent_line_number: 8
fingerprint: 55db11cd18d0af4114644d01cefbc79d_2
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_2
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 11
full_filename: import.py
filename: import.py
source:
location:
start: 11
end: 11
column:
start: 1
end: 17
sink:
location:
start: 11
end: 11
column:
start: 1
end: 17
content: ""
parent_line_number: 11
fingerprint: 55db11cd18d0af4114644d01cefbc79d_3
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_3
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 14
full_filename: import.py
filename: import.py
source:
location:
start: 14
end: 14
column:
start: 1
end: 17
sink:
location:
start: 14
end: 14
column:
start: 1
end: 17
content: ""
parent_line_number: 14
fingerprint: 55db11cd18d0af4114644d01cefbc79d_4
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_4
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 17
full_filename: import.py
filename: import.py
source:
location:
start: 17
end: 17
column:
start: 1
end: 17
sink:
location:
start: 17
end: 17
column:
start: 1
end: 17
content: ""
parent_line_number: 17
fingerprint: 55db11cd18d0af4114644d01cefbc79d_5
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_5
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 20
full_filename: import.py
filename: import.py
source:
location:
start: 20
end: 20
column:
start: 1
end: 20
sink:
location:
start: 20
end: 20
column:
start: 1
end: 20
content: ""
parent_line_number: 20
fingerprint: 55db11cd18d0af4114644d01cefbc79d_6
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_6
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 23
full_filename: import.py
filename: import.py
source:
location:
start: 23
end: 23
column:
start: 1
end: 16
sink:
location:
start: 23
end: 23
column:
start: 1
end: 16
content: ""
parent_line_number: 23
fingerprint: 55db11cd18d0af4114644d01cefbc79d_7
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_7
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 26
full_filename: import.py
filename: import.py
source:
location:
start: 26
end: 26
column:
start: 1
end: 23
sink:
location:
start: 26
end: 26
column:
start: 1
end: 23
content: ""
parent_line_number: 26
fingerprint: 55db11cd18d0af4114644d01cefbc79d_8
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_8
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 30
full_filename: import.py
filename: import.py
source:
location:
start: 30
end: 30
column:
start: 1
end: 11
sink:
location:
start: 30
end: 30
column:
start: 1
end: 11
content: ""
parent_line_number: 30
fingerprint: 55db11cd18d0af4114644d01cefbc79d_9
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_9
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 34
full_filename: import.py
filename: import.py
source:
location:
start: 34
end: 34
column:
start: 1
end: 11
sink:
location:
start: 34
end: 34
column:
start: 1
end: 11
content: ""
parent_line_number: 34
fingerprint: 55db11cd18d0af4114644d01cefbc79d_10
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_10
- rule:
cwe_ids:
- "42"
id: import_test
title: Test detection filter import statements
description: Test detection filter import statements
documentation_url: ""
line_number: 38
full_filename: import.py
filename: import.py
source:
location:
start: 38
end: 38
column:
start: 1
end: 11
sink:
location:
start: 38
end: 38
column:
start: 1
end: 11
content: ""
parent_line_number: 38
fingerprint: 55db11cd18d0af4114644d01cefbc79d_11
old_fingerprint: 55db11cd18d0af4114644d01cefbc79d_11

23 changes: 23 additions & 0 deletions internal/languages/python/analyzer/analyzer.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ func (analyzer *analyzer) Analyze(node *sitter.Node, visitChildren func() error)
return analyzer.analyzeConditional(node, visitChildren)
case "boolean_operator":
return analyzer.analyzeBoolean(node, visitChildren)
case "import_statement", "import_from_statement":
return analyzer.analyzeImport(node, visitChildren)
case "identifier":
return visitChildren()
default:
Expand Down Expand Up @@ -159,6 +161,27 @@ func (analyzer *analyzer) analyzeKeywordArgument(node *sitter.Node, visitChildre
return visitChildren()
}

// import x
// import a.b
// from z import x
// import x as y (aliased_import)
// from z import x as y (aliased_import)
func (analyzer *analyzer) analyzeImport(node *sitter.Node, visitChildren func() error) error {
children := analyzer.builder.ChildrenExcept(node, node.ChildByFieldName("module_name"))

for _, child := range children {
switch child.Type() {
case "aliased_import":
aliasedImportIdentifier := child.ChildByFieldName("alias")
analyzer.scope.Declare(analyzer.builder.ContentFor(aliasedImportIdentifier), aliasedImportIdentifier)
case "dotted_name":
analyzer.scope.Declare(analyzer.builder.ContentFor(child.NamedChild(0)), child.NamedChild(0))
}
}

return nil
}

// default analysis, where the children are assumed to be aliases
func (analyzer *analyzer) analyzeGenericConstruct(node *sitter.Node, visitChildren func() error) error {
children := analyzer.builder.ChildrenFor(node)
Expand Down
7 changes: 6 additions & 1 deletion internal/languages/python/pattern/pattern.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ var (
matchNodeRegex = regexp.MustCompile(`\$<!>`)
ellipsisRegex = regexp.MustCompile(`\$<\.\.\.>`)
unanchoredPatternNodeTypes = []string{}
patternMatchNodeContainerTypes = []string{}
patternMatchNodeContainerTypes = []string{"dotted_name"}

allowedPatternQueryTypes = []string{"_"}
)
Expand Down Expand Up @@ -129,6 +129,11 @@ func (*Pattern) IsAnchored(node *tree.Node) (bool, bool) {
return false, false
}

if (parent.Type() == "import_statement" || parent.Type() == "import_from_statement" || parent.Type() == "relative_import") &&
(node.Type() == "dotted_name" || node.Type() == "aliased_import") {
return false, false
}

// Class body declaration_list
// function/block compound_statement
unAnchored := []string{}
Expand Down

0 comments on commit 7ecf89c

Please sign in to comment.