
trailmark v0.5.0
स्रोत कोड के ग्राफ डेटाबेस प्रतिनिधित्व का निर्माण और क्वेरी करें
Trailmark
सुरक्षा विश्लेषण के लिए स्रोत कोड को फ़ंक्शन, क्लास, कॉल और सिमैंटिक एनोटेशन के क्वेरी-योग्य ग्राफ़ में पार्स करें।
Trailmark भाषा-अज्ञेयवादी AST पार्सिंग के लिए tree-sitter और उच्च-प्रदर्शन ग्राफ़ ट्रैवर्सल के लिए rustworkx का उपयोग करता है। दीर्घकालिक दृष्टि इस ग्राफ़ को म्यूटेशन टेस्टिंग और कवरेज-निर्देशित फ़ज़िंग के साथ जोड़कर उन अंतरालों की पहचान करना है जो मान्यताओं और परीक्षण कवरेज के बीच मौजूद हैं और उपयोगकर्ता इनपुट से पहुँच योग्य हैं।
यह कैसे काम करता है
Trailmark तीन चरणों में संचालित होता है: parse, index, और query।
flowchart TD
A["Source Files"] --> B["tree-sitter Parser"]
B --> C["CodeGraph (nodes + edges)"]
C --> D["rustworkx GraphStore"]
D --> E["QueryEngine"]
E --> F["JSON / Summary / Hotspots"]
classDef src fill:#007bff26,stroke:#007bff,color:#007bff
classDef parse fill:#28a74526,stroke:#28a745,color:#28a745
classDef data fill:#6f42c126,stroke:#6f42c1,color:#6f42c1
classDef query fill:#ffc10726,stroke:#e6a817,color:#e6a817
class A src
class B parse
class C,D data
class E,F query
1. पार्स करें
एक भाषा-विशिष्ट पार्सर निर्देशिका में चलता है, प्रत्येक फ़ाइल को tree-sitter AST में पार्स करता है, और निकालता है:
- नोड्स — फ़ंक्शन, मेथड्स, क्लासेस, स्ट्रक्ट्स, इंटरफ़ेस, ट्रेट्स, एनम्स, मॉड्यूल, नेमस्पेस
- एजेस — कॉल्स, इनहेरिटेंस, इम्प्लीमेंटेशन, कंटेनमेंट, इम्पोर्ट्स
- मेटाडेटा — टाइप एनोटेशन, साइक्लोमैटिक कॉम्प्लेक्सिटी, ब्रांचेस, डॉकस्ट्रिंग्स, एक्सेप्शन टाइप्स
समर्थित भाषाएँ
| भाषा | एक्सटेंशन | मुख्य कंस्ट्रक्ट्स |
|---|---|---|
| Python | .py | फ़ंक्शन, क्लासेस, मेथड्स |
| JavaScript | .js, .jsx, .mjs, .cjs | फ़ंक्शन, क्लासेस, एरो फ़ंक्शन |
| TypeScript | .ts, .tsx | फ़ंक्शन, क्लासेस, इंटरफ़ेस, एनम्स |
| PHP | .php | फ़ंक्शन, क्लासेस, इंटरफ़ेस, ट्रेट्स |
| Ruby | .rb | मेथड्स, क्लासेस, मॉड्यूल |
| C | .c, .h | फ़ंक्शन, स्ट्रक्ट्स, एनम्स |
| C++ | .cpp, .hpp, .cc, .hh, .cxx, .hxx | फ़ंक्शन, क्लासेस, स्ट्रक्ट्स, नेमस्पेस |
| C# | .cs | मेथड्स, क्लासेस, इंटरफ़ेस, स्ट्रक्ट्स, एनम्स, नेमस्पेस |
| Java | .java | मेथड्स, क्लासेस, इंटरफ़ेस, एनम्स |
| Go | .go | फ़ंक्शन, मेथड्स, स्ट्रक्ट्स, इंटरफ़ेस |
| Rust | .rs | फ़ंक्शन, स्ट्रक्ट्स, ट्रेट्स, एनम्स, impl ब्लॉक्स, verus! ब्लॉक्स |
| Solidity | .sol | कॉन्ट्रैक्ट्स, इंटरफ़ेस, लाइब्रेरीज़, फ़ंक्शन, मॉडिफ़ायर्स, स्ट्रक्ट्स, एनम्स |
| Cairo | .cairo | फ़ंक्शन, ट्रेट्स, स्ट्रक्ट्स, एनम्स, impl ब्लॉक्स, StarkNet कॉन्ट्रैक्ट्स |
| Circom | .circom | टेम्पलेट्स, फ़ंक्शन, सिग्नल्स, कंपोनेंट्स |
| Haskell | .hs | फ़ंक्शन, डेटा टाइप्स, टाइप क्लासेस, इंस्टेंसेस |
| Erlang | .erl | फ़ंक्शन, रिकॉर्ड्स, बिहेवियर्स, मॉड्यूल |
| Miden Assembly | .masm | प्रोसीजर्स, एंट्रीपॉइंट्स, कॉन्स्टेंट्स, इन्वोकेशन्स |
| Swift | .swift | फ़ंक्शन, क्लासेस, स्ट्रक्ट्स, एनम्स, प्रोटोकॉल्स, एक्सटेंशन्स |
| Objective-C | .m, .mm, .h | C फ़ंक्शन, क्लासेस, मेथड्स (सेलेक्टर-आधारित नामकरण) |
| Kotlin | .kt, .kts | फ़ंक्शन, क्लासेस, इंटरफ़ेस, डेटा क्लासेस, ऑब्जेक्ट्स, मेथड्स |
| Dart | .dart | फ़ंक्शन, क्लासेस, एब्सट्रैक्ट क्लासेस, मेथड्स, कंस्ट्रक्टर्स |
| Move | .move | मॉड्यूल, फ़ंक्शन, इम्पोर्ट्स, डायरेक्ट कॉल्स |
| Tact | .tact | कॉन्ट्रैक्ट्स, स्ट्रक्ट्स, रिसीवर्स, फ़ंक्शन |
| Func | .fc, .func | फ़ंक्शन, इन्क्लूड्स, डायरेक्ट कॉल्स |
| Sway | .sw | ABI इंटरफ़ेस, स्ट्रक्ट्स, impl मेथड्स, फ़ंक्शन |
| Rego | .rego | पैकेजेस, इम्पोर्ट्स, पॉलिसी रूल्स, रूल कॉल्स |
| Proto | .proto | सर्विसेस, RPCs, मैसेजेस, फ़ील्ड्स, एनम्स |
| Thrift | .thrift | सर्विसेस, फ़ंक्शन, स्ट्रक्ट्स, फ़ील्ड्स, एनम्स |
| GraphQL | .graphql, .gql | ऑब्जेक्ट टाइप्स, रूट ऑपरेशन्स, फ़ील्ड्स, एनम्स |
| SQL | .sql | स्कीमाज़, टेबल्स, व्यूज़, फ़ंक्शन, प्रोसीजर्स |
Rust पार्सर verus! { ... } ब्लॉक्स से सामान्य, spec, और proof फ़ंक्शन्स को उनके बॉडीज़ सहित निकालता है। Verus व्याकरण वर्तमान में केवल ब्रेस-सीमांकित ब्लॉक्स का समर्थन करता है; verus!(...) और verus![...] को चेतावनी के साथ छोड़ दिया जाता है। इनलाइन मॉड्यूल योग्य ID बनाए रखते हैं (उदाहरण के लिए, file.inner:function), और मेथड्स अपने impl या trait स्वामी को बनाए रखते हैं। प्रत्येक ब्लॉक को स्वतंत्र रूप से पार्स किया जाता है; सिंटैक्स त्रुटियाँ फ़ाइल और ब्लॉक स्थान के साथ चेतावनी उत्पन्न करती हैं। vstd::prelude::verus! जैसे योग्य इनवोकेशन्स का भी समर्थन किया जाता है। स्थानीय हेल्पर फ़ंक्शन्स अपने ID में अपने संलग्न फ़ंक्शन को बनाए रखते हैं (उदाहरण के लिए, file:outer.inner)। इन हेल्पर्स के कॉल्स और use super::* जैसे सापेक्ष इम्पोर्ट्स फ़ाइल में मौजूद डिक्लेरेशन्स पर रिज़ॉल्व होते हैं। विभिन्न ब्लॉक्स में दोहराए गए स्थानीय नामों को उनके नोड्स को अलग रखने के लिए बाइट-ऑफ़सेट सफ़िक्स मिलता है, और कॉल्स ब्लॉक स्कोप का सम्मान करते हैं। स्थानीय स्ट्रक्ट्स, एनम्स, ट्रेट्स, और इनलाइन मॉड्यूल भी संलग्न फ़ंक्शन को बनाए रखते हैं: उदाहरण के लिए, file:outer.Guard.drop और file:outer.local.helper। उनके बॉडीज़ में अलग कॉल्स और जटिलता होती है। ज्ञात स्थानीय टाइप्स और मॉड्यूल्स के स्पष्ट कॉल्स फ़ाइल के भीतर रिज़ॉल्व होते हैं। बेयर कॉल्स फ़ंक्शन और मॉड्यूल स्कोप्स में खोजते हैं; एसोसिएटेड आइटम्स Type::method जैसे पाथ्स का उपयोग करते हैं। डॉटेड कॉल्स केवल तब रिज़ॉल्व होते हैं जब रिसीवर किसी ज्ञात स्ट्रक्ट या एनम का नाम देता है। अन्य वैल्यू रिसीवर्स, जिनमें self.method() शामिल है, अनरिज़ॉल्व्ड रहते हैं। इम्प्लिसिट डिस्ट्रक्टर कॉल्स और रिसीवर टाइप इन्फ़रेंस को मॉडल नहीं किया जाता है। ये नियम सामान्य Rust के साथ-साथ Verus ब्लॉक्स पर भी लागू होते हैं। ऑफ़सेट सफ़िक्स वाले डिक्लेरेशन से पहले कोड एडिट करने से उसका ID बदल जाता है, इसलिए trailmark diff उस डिक्लेरेशन को हटाया गया और जोड़ा गया के रूप में रिपोर्ट कर सकता है।
Trailmark मनमाने मैक्रोज़ का विस्तार नहीं करता है। अपारदर्शी मैक्रोज़ या फ़ंक्शन बॉडीज़ के अंदर शाब्दिक Verus इनवोकेशन्स को चेतावनी के साथ छोड़ दिया जाता है। अनइनवोक्ड macro_rules! परिभाषाओं का विस्तार नहीं किया जाता है। बॉडीज़ के बिना फ़ंक्शन सिग्नेचर्स और requires/ensures क्लॉज़ में कॉल्स को निकाला नहीं जाता है।
flowchart TD
subgraph "Per-File Parsing"
F["Source file"] --> TS["tree-sitter AST"]
TS --> EX["Extract nodes"]
TS --> EC["Extract call edges"]
TS --> EB["Count branches"]
TS --> ET["Resolve types"]
end
EX --> CG["CodeGraph"]
EC --> CG
EB --> CG
ET --> CG
classDef src fill:#007bff26,stroke:#007bff,color:#007bff
classDef parse fill:#28a74526,stroke:#28a745,color:#28a745
classDef extract fill:#ffc10726,stroke:#e6a817,color:#e6a817
classDef data fill:#6f42c126,stroke:#6f42c1,color:#6f42c1
class F src
class TS parse
class EX,EC,EB,ET extract
class CG data
Node ID module:function, module:Class, या स्पष्ट लुकअप के लिए module:Class.method योजना का पालन करते हैं। डायरेक्टरी पार्सिंग एक अद्वितीय परिभाषा मौजूद होने पर बेयर क्रॉस-फ़ाइल कॉल्स को हल करती है; अस्पष्ट क्रॉस-फ़ाइल कॉल्स को उनके मूल बेस्ट-एफर्ट लक्ष्य पर छोड़ दिया जाता है और uncertain के रूप में चिह्नित किया जाता है। एज कॉन्फिडेंस को certain (प्रत्यक्ष कॉल्स, self.method()), inferred (गैर-self ऑब्जेक्ट्स पर एट्रिब्यूट एक्सेस), या uncertain (डायनामिक डिस्पैच या अस्पष्ट रिज़ॉल्यूशन) के रूप में टैग किया जाता है।
2. Index
GraphStore CodeGraph को एक rustworkx PyDiGraph में लोड करता है और तेज़ ट्रैवर्सल के लिए द्विदिशात्मक ID/index मैपिंग बनाता है।
3. Query
QueryEngine इंडेक्स्ड ग्राफ़ पर एक उच्च-स्तरीय API प्रदान करता है: