cybersecurity · intermediate · ~25 min
Pattern-based string rewriting in place; respecting buffer bounds.
Strip email addresses from a log line before it ships to a centralised service — the smallest example of PII redaction every production logger eventually needs.
Implement void redact_emails(char *line) that mutates line in place, replacing every email-like substring with the literal text [redacted].
An email-like substring is a maximal run matching this loose pattern:
[A-Za-z0-9._+-] (the local part)@[A-Za-z0-9.-] (the domain).[A-Za-z] (the TLD)line: a NUL-terminated, writable buffer. The grader passes a fixed line. Assume strlen(line) < 2048.No return value. line is rewritten in place with every email replaced by [redacted].
"alice@example.com signed in" -> "[redacted] signed in"
"User bob.smith+spam@example.co.uk forgot password" -> "User [redacted] forgot password"
"no email here" -> "no email here"
"two: a@b.com and c@d.io" -> "two: [redacted] and [redacted]"
"weird a@b.x stuff" -> "weird a@b.x stuff" (1-letter TLD: not an email)
a@b.x) does not match.@, a@, @b: not emails.Shipping logs to a centralised analytics service often runs afoul of privacy laws (GDPR, CCPA) unless personally identifiable information is stripped first. Email redaction is the smallest example of the kind of pipeline-stage redaction that every production logger eventually needs.
A NUL-terminated, writable line (assume length < 2 KB).
No return value; line is mutated so every email becomes [redacted].
Rewrite in place; no heap allocation; a 2+-letter TLD is required to match.
void redact_emails(char *line) { /* TODO */ }
Replacing only the first match. Allocating a new buffer (the contract is in-place).
No email; multiple emails; email at the very start or end; pathological-looking strings that aren't actually emails (@, a@, @b).
O(strlen(line)).
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.