Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MODULE.bazel.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions codex-rs/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions codex-rs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ tonic = { version = "0.14.3", default-features = false, features = ["channel", "
tonic-prost = "0.14.3"
tree-sitter = "0.25.10"
tree-sitter-bash = "0.25"
tree-sitter-powershell = "=0.26.4"
ts-rs = "11"
tungstenite = { version = "0.27.0", features = ["deflate", "proxy"] }
uds_windows = "1.1.0"
Expand Down
5 changes: 4 additions & 1 deletion codex-rs/shell-command/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ load("//:defs.bzl", "codex_rust_crate")

codex_rust_crate(
name = "shell-command",
compile_data = ["src/command_safety/powershell_parser.ps1"],
compile_data = [
"src/command_safety/fixtures/powershell_lowering.json",
"src/command_safety/powershell_parser.ps1",
],
crate_name = "codex_shell_command",
)
1 change: 1 addition & 0 deletions codex-rs/shell-command/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ serde_json = { workspace = true }
shlex = { workspace = true }
tree-sitter = { workspace = true }
tree-sitter-bash = { workspace = true }
tree-sitter-powershell = { workspace = true }
url = { workspace = true }
which = { workspace = true }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
[
{"name":"echo","script":"echo hi","expected":[["echo","hi"]]},
{"name":"single_quote","script":"Get-Content 'foo bar'","expected":[["Get-Content","foo bar"]]},
{"name":"quoted_comma","script":"Get-Content 'foo,bar'","expected":[["Get-Content","foo,bar"]]},
{"name":"double_quote","script":"Get-Content \"foo bar\"","expected":[["Get-Content","foo bar"]]},
{"name":"doubled_single_quote","script":"Write-Output 'a''b'","expected":[["Write-Output","a'b"]]},
{"name":"escaped_double_quote","script":"Write-Output \"a`\"b\"","expected":[["Write-Output","a\"b"]]},
{"name":"powershell_7_escape_in_double_quote","script":"rg \"--pr`e=helper.exe\" pattern","expected":null},
{"name":"unicode_escape_in_double_quote","script":"rg \"--pre=`u{68}elper.exe\" pattern","expected":null},
{"name":"escaped_space","script":"Get-Content foo` bar","expected":[["Get-Content","foo bar"]]},
{"name":"powershell_7_escape_in_bare_word","script":"rg --pr`e helper.exe pattern","expected":null},
{"name":"command_parameter","script":"Get-ChildItem -Path .","expected":[["Get-ChildItem","-Path","."]]},
{"name":"attached_parameter_argument","script":"Get-Content -Path:1","expected":null},
{"name":"attached_quoted_parameter_argument","script":"Get-Content -Path:'foo bar'","expected":null},
{"name":"pipeline","script":"Write-Output foo | Measure-Object","expected":[["Write-Output","foo"],["Measure-Object"]]},
{"name":"semicolon","script":"Get-Content Cargo.toml; Test-Path Cargo.toml","expected":[["Get-Content","Cargo.toml"],["Test-Path","Cargo.toml"]]},
{"name":"and_chain","script":"pwd && ls","expected":[["pwd"],["ls"]]},
{"name":"or_chain","script":"pwd || ls","expected":[["pwd"],["ls"]]},
{"name":"parenthesized_command","script":"(Get-Content foo.rs -Raw)","expected":null},
{"name":"parenthesized_pipeline","script":"(Get-Content foo | Measure-Object)","expected":null},
{"name":"parenthesized_chain","script":"(pwd && ls)","expected":null},
{"name":"canonical_numeric_argument","script":"Get-Content -TotalCount 100","expected":[["Get-Content","-TotalCount","100"]]},
{"name":"negative_numeric_argument","script":"git log -1 Cargo.toml","expected":[["git","log","-1","Cargo.toml"]]},
{"name":"hexadecimal_numeric_argument","script":"Write-Output 0x10","expected":null},
{"name":"signed_hexadecimal_numeric_argument","script":"Write-Output 0xFFFFFFFF","expected":null},
{"name":"binary_numeric_argument","script":"Write-Output 0b101","expected":null},
{"name":"type_suffixed_numeric_argument","script":"Write-Output 1d","expected":null},
{"name":"powershell_7_type_suffixed_numeric_argument","script":"Write-Output 1u","expected":null},
{"name":"size_suffixed_numeric_argument","script":"Write-Output 1kb","expected":null},
{"name":"leading_zero_numeric_argument","script":"Write-Output 01","expected":null},
{"name":"real_numeric_argument","script":"Write-Output 1.0","expected":null},
{"name":"exponent_numeric_argument","script":"Write-Output 1e3","expected":null},
{"name":"numeric_leading_filename","script":"Get-Content 1.0.0","expected":null},
{"name":"inline_double_dash_parameter","script":"Get-Content --flag=value","expected":[["Get-Content","--flag=value"]]},
{"name":"inline_double_dash_parameter_pipeline","script":"Get-Content --flag=value | Measure-Object","expected":[["Get-Content","--flag=value"],["Measure-Object"]]},
{"name":"git_dir_inline","script":"git --git-dir=.git status","expected":[["git","--git-dir=.git","status"]]},
{"name":"windows_path","script":"Get-Content C:\\tmp\\x","expected":[["Get-Content","C:\\tmp\\x"]]},
{"name":"verbatim_here_string","script":"Write-Output @'\nhello\n'@","expected":null},
{"name":"expandable_here_string_without_expansion","script":"Write-Output @\"\nhello\n\"@","expected":null},
{"name":"expandable_here_string_with_escaped_dollar","script":"Write-Output @\"\n`$foo\n\"@","expected":null},
{"name":"dangerous_literal_url","script":"Start-Process 'https://example.com'","expected":[["Start-Process","https://example.com"]]},
{"name":"dangerous_literal_force","script":"Remove-Item test -Force","expected":[["Remove-Item","test","-Force"]]},
{"name":"unicode_dash_parameter","script":"Remove-Item test –Force","expected":null},
{"name":"trailing_comment","script":"Get-Content Cargo.toml # comment","expected":[["Get-Content","Cargo.toml"]]},
{"name":"hash_inside_token","script":"Get-Content foo#bar","expected":[["Get-Content","foo#bar"]]},
{"name":"embedded_hash_before_separator","script":"git status --short#; Remove-Item victim","expected":null},
{"name":"smart_quote_delimiter","script":"rg “--pre=helper.exe” pattern","expected":null},
{"name":"hash_inside_recovered_command_token","script":"pwd#evil --flag=value","expected":[["pwd#evil","--flag=value"]]},
{"name":"block_comment_before_command","script":"<# note #>\nGet-Content foo","expected":[["Get-Content","foo"]]},
{"name":"stop_parsing","script":"git log --% HEAD --output=codex_poc.txt","expected":null},
{"name":"param_block","script":"param([string]$path = (Get-Location)) Write-Output test","expected":null},
{"name":"named_blocks","script":"begin { Set-Content codex_poc.txt pwned } end { Get-Content Cargo.toml }","expected":null},
{"name":"using_statement","script":"using module ./codex_poc.psm1\nGet-Content Cargo.toml","expected":null},
{"name":"mixed_case_using_statement","script":"Using module ./codex_poc.psm1\nGet-Content Cargo.toml","expected":null},
{"name":"trap_block","script":"trap { Set-Content codex_poc.txt pwned; continue } Get-Content missing -ErrorAction Stop","expected":null},
{"name":"redirection","script":"echo hi > out.txt","expected":null},
{"name":"invocation_operator","script":"& Remove-Item foo","expected":null},
{"name":"nested_command","script":"Write-Output (Set-Content foo6.txt 'abc')","expected":null},
{"name":"subexpression","script":"Write-Output $(Get-Content foo)","expected":null},
{"name":"array_expression","script":"ls @(calc.exe)","expected":null},
{"name":"splat","script":"Get-Content @args","expected":null},
{"name":"empty_word","script":"''","expected":null},
{"name":"dynamic_argument","script":"Get-Content $foo","expected":null},
{"name":"expandable_dynamic","script":"Write-Output \"foo $bar\"","expected":null},
{"name":"comma_form","script":"Get-Content foo,bar","expected":null},
{"name":"single_dash_equals_is_not_recovery","script":"Get-Content -foo=bar","expected":null},
{"name":"uncovered_closing_paren","script":"Get-Content --flag=value )","expected":null},
{"name":"uncovered_invalid_tail","script":"Get-Content --flag=value | if (","expected":null},
{"name":"dangling_escape_after_recovery","script":"Get-Content --flag=value `","expected":null}
]
3 changes: 3 additions & 0 deletions codex-rs/shell-command/src/command_safety/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
mod powershell_parser;
// Production safety and exec-policy callers migrate to this lowerer in a follow-up.
#[allow(dead_code)]
mod powershell_tree_sitter;

pub mod is_dangerous_command;
pub mod is_safe_command;
Expand Down
Loading
Loading