Skip to main content

agentshield/parser/
mod.rs

1pub(crate) mod common;
2pub mod json_schema;
3pub mod python;
4pub mod shell;
5pub mod typescript;
6
7use std::collections::HashSet;
8use std::path::Path;
9
10use crate::error::Result;
11use crate::ir::execution_surface::*;
12use crate::ir::{ArgumentSource, Language, SourceLocation};
13
14/// Result of parsing a single source file.
15#[derive(Debug, Clone, Default)]
16pub struct ParsedFile {
17    pub commands: Vec<CommandInvocation>,
18    pub file_operations: Vec<FileOperation>,
19    pub network_operations: Vec<NetworkOperation>,
20    pub env_accesses: Vec<EnvAccess>,
21    pub dynamic_exec: Vec<DynamicExec>,
22    /// Names of function parameters (for tool argument tracking).
23    pub function_params: Vec<FunctionParam>,
24    /// Function definitions discovered in source code.
25    pub function_defs: Vec<FunctionDef>,
26    /// Function call sites discovered in source code.
27    pub call_sites: Vec<CallSite>,
28    /// Variables holding sanitized values (e.g., `validPath = validatePath(x)`).
29    pub sanitized_vars: HashSet<String>,
30}
31
32/// A function parameter discovered in source code.
33#[derive(Debug, Clone)]
34pub struct FunctionParam {
35    pub function_name: String,
36    pub param_name: String,
37    pub location: SourceLocation,
38}
39
40/// A function definition discovered in source code.
41#[derive(Debug, Clone)]
42pub struct FunctionDef {
43    pub name: String,
44    pub params: Vec<String>,
45    pub is_exported: bool,
46    pub location: SourceLocation,
47}
48
49/// A function call site discovered in source code.
50#[derive(Debug, Clone)]
51pub struct CallSite {
52    /// The function being called.
53    pub callee: String,
54    /// Arguments passed, each classified.
55    pub arguments: Vec<ArgumentSource>,
56    /// The enclosing function name, if any.
57    pub caller: Option<String>,
58    pub location: SourceLocation,
59}
60
61/// Language parser trait. Each parser extracts security-relevant operations
62/// from source files.
63pub trait LanguageParser: Send + Sync {
64    fn language(&self) -> Language;
65    fn parse_file(&self, path: &Path, content: &str) -> Result<ParsedFile>;
66}
67
68/// Get the appropriate parser for a language.
69pub fn parser_for_language(lang: Language) -> Option<Box<dyn LanguageParser>> {
70    match lang {
71        Language::Python => Some(Box::new(python::PythonParser)),
72        Language::TypeScript | Language::JavaScript => Some(Box::new(typescript::TypeScriptParser)),
73        Language::Shell => Some(Box::new(shell::ShellParser)),
74        _ => None,
75    }
76}