Progress towards tree-sitter feature#3102
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces Tree-Sitter Script Analysis to capa, enabling feature extraction from script languages such as C#, Python, HTML, and ASPX templates. It adds a new Tree-Sitter-based feature extractor, auto-detection capabilities, and signature-based tools, along with comprehensive tests and updated dependencies. The code review feedback primarily addresses compatibility issues with the upgraded tree-sitter library (version 0.25.0), specifically pointing out that QueryCursor has been removed and the Parser instantiation has changed in tree-sitter versions >= 0.21.0. The feedback provides actionable suggestions to execute queries directly and update parser usage. Additionally, it identifies a bug in integer suffix parsing and recommends replacing a deprecated importlib.resources API.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
e71ca37 to
5c19383
Compare
2e75cd1 to
050ab84
Compare
Revives and supersedes old PR mandiant#1080. Resolves merge conflicts and brings up to date with current master.
46a6446 to
19308f7
Compare
|
@mike-hunhoff @larchchen @Maijin The first version of the script analysis feature is ready for review. |
mr-tz
left a comment
There was a problem hiding this comment.
Initial review of the first few files
|
|
||
| def get_language_from_ext(path: str) -> str: | ||
| if path.endswith(EXT_ASPX): | ||
| return LANG_TEM |
There was a problem hiding this comment.
Embedded template is not immediately clear to me, some doc on that would be good (maybe it is further down).
There was a problem hiding this comment.
I haven’t added documentation yet, but I’ll add a section describing the script analysis feature in the near future.
| buf = f.read() | ||
| return get_language_ts(buf) | ||
| except ValueError: | ||
| return get_language_from_ext(str(path)) |
There was a problem hiding this comment.
I guess the order is debatable here, so flagging for further discussion
There was a problem hiding this comment.
My thinking here was to prefer Tree-sitter’s language detection when possible, since it can inspect the file contents rather than relying only on the extension. The extension fallback is mainly for cases where content-based detection fails.
That said, I agree that the order is debatable. Happy to discuss more on this!
There was a problem hiding this comment.
What's the performance difference if we switch the order? My concern is that Tree-sitter's language detection could be slow for large or heavily obfuscated scripts, while simply checking the extension won't be bogged down by script size or complexity.
There was a problem hiding this comment.
I ran a small benchmark test with simple Python scripts of different file sizes. There is actually a huge difference in the time taken by content-based detection compared to extension-based detection.
- Extension-based: 0.0005 ms
- Content-based: 7.3845 ms
So, it would be optimal for us to have extension-based detection first. Thank you for pointing it out @mr-tz and @mike-hunhoff.
I will correct it in the next commit.
|
Kudo for making this huge pr work 👍, I have two high-level comments mainly:
|
| @@ -0,0 +1,95 @@ | |||
| { | |||
| "classes" : [ | |||
| "System.Data.SqlClient.SqlCommand", | |||
There was a problem hiding this comment.
Would recommend sorting all of these signatures everywhere. This will ease contributions.
| @@ -0,0 +1,47 @@ | |||
| { | |||
| "classes": [ | |||
| "socket.socket", | |||
There was a problem hiding this comment.
Same here - sort everywhere
Sure, Maxime. We can discuss about the architecture in the upcoming meets. |
mr-tz
left a comment
There was a problem hiding this comment.
nice progress overall, thanks for all the work on getting this feature finally integrated :)
eefa6da to
3da5825
Compare
3da5825 to
2b25c67
Compare
mike-hunhoff
left a comment
There was a problem hiding this comment.
Thank you @saniyafatima07 , I know this is a large PR to work with, so thank you for all you've done so far. I've left comments for your review. Mostly it appears that the PR still contains unrelated changes, likely from some rebase conflicts?
| buf = f.read() | ||
| return get_language_ts(buf) | ||
| except ValueError: | ||
| return get_language_from_ext(str(path)) |
There was a problem hiding this comment.
What's the performance difference if we switch the order? My concern is that Tree-sitter's language detection could be slow for large or heavily obfuscated scripts, while simply checking the extension won't be bogged down by script size or complexity.
|
|
||
| ### New Features | ||
|
|
||
| - Tree-Sitter Script Analysis |
There was a problem hiding this comment.
TODO: expand this description to include contributions from previous developers.
Thank you for the review, Mike. I looked into all the comments. It seems like I messed up a few things during the rebase, which caused a lot of unrelated changes. I will carefully look into all the unrelated changes and resolve them. |
0582aff to
d12e8d5
Compare
Addresses PR #1080 and #2931
This PR updates capa’s Tree-sitter support for script analysis and fixes the related integration issues so the feature works correctly in both source and packaged builds.
Changes include:
Checklist
Parts of this implementation were assisted using AI tools (Codex and ChatGPT).
AI was used for:
All code was reviewed, modified and tested manually before submission.
Testing:

I built it using PyInstaller and tested the capabilities on script inputs. It functions as intended.