cybersecurity · intermediate · ~20 min
Allow-list filtering, leading-dot rule, and length capping in one pass.
Implement void sanitize_filename(char *s) that mutates s in place so it contains only safe characters. Replace any byte that is NOT in the allow-list with an underscore (_).
Allow-list:
A-Z, a-z0-9_, -, .Additionally, the function must:
. with _ (no hidden files).'\0' at index 64)."hello.txt" -> "hello.txt"
"hello world.txt" -> "hello_world.txt"
"../etc/passwd" -> "_._etc_passwd"
".htaccess" -> "_htaccess"
"a"*100 -> first 64 'a's, then NUL
"normal_name-1.tar.gz" -> "normal_name-1.tar.gz"
"" -> ""
When a user uploads a file or names an export, the filename is attacker-controlled. Allowing arbitrary bytes invites path traversal, NUL injection, hidden-file creation (.htaccess), and shell-special bytes. A short allowlist scrub is the standard defensive answer.
Mutable null-terminated string.
s is mutated.
Single pass; 64-character cap. No allocations.
void sanitize_filename(char *s) { /* TODO */ }
Using a deny-list (if (c == '/' || c == '\\') ...) — endlessly incomplete. Forgetting the leading-dot rule.
Empty; leading dot; all special chars; longer than 64.
O(strlen(s)).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.