cybersecurity · intermediate · ~25 min

Redact email addresses in a log line

Pattern-based string rewriting in place; respecting buffer bounds.

Challenge

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:

  • one or more characters in [A-Za-z0-9._+-]
  • a literal @
  • one or more characters in [A-Za-z0-9.-]
  • a literal .
  • two or more letters in [A-Za-z]

The function uses the same buffer (no allocations). The line is null-terminated and writable; the replacement is shorter than or equal to most addresses so this fits without growth — but we cap the output at the original buffer length.

For practical purposes you may assume strlen(line) < 2048 and you are given the same buffer to mutate.

Examples

"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]"

Why this matters

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.

Input format

Null-terminated mutable line, max length ~2 KB.

Output format

line mutated; every email replaced with [redacted].

Constraints

In-place rewriting. Assume buffer length is enough for the resulting line (replacements are no longer than the originals for short addresses; we still cap at the buffer's original size to be safe).

Starter code

void redact_emails(char *line) { /* TODO */ }

Common mistakes

Replacing only the first match. Allocating a new buffer (the contract is in-place).

Edge cases to handle

No email; multiple emails; email at the very start or end; pathological-looking strings that aren't actually emails (@, a@, @b).

Complexity

O(strlen(line)).

Background lessons

Up next

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.