| 2486 | } |
| 2487 | |
| 2488 | static bool cbm_hook_script_name_safe(const char *script_name) { |
| 2489 | if (!script_name || !script_name[0]) { |
| 2490 | return false; |
| 2491 | } |
| 2492 | for (const unsigned char *cursor = (const unsigned char *)script_name; *cursor; cursor++) { |
| 2493 | bool safe = (*cursor >= 'a' && *cursor <= 'z') || (*cursor >= 'A' && *cursor <= 'Z') || |
| 2494 | (*cursor >= '0' && *cursor <= '9') || *cursor == '-' || *cursor == '_' || |
| 2495 | *cursor == '.'; |
| 2496 | if (!safe) { |
| 2497 | return false; |
| 2498 | } |
| 2499 | } |
| 2500 | return true; |
| 2501 | } |
| 2502 | |
| 2503 | /* Build the hook command string written into Claude Code's settings.json. |
| 2504 | * POSIX embeds a safely quoted absolute custom config path or a portable $HOME |
no outgoing calls
no test coverage detected