cybersecurity · beginner · ~15 min · safe pentest lab
Learn to parse an untrusted delimited string defensively: count tokens while rejecting empty tokens (leading, trailing, and consecutive delimiters), and fail closed on NULL/empty input instead of returning a plausible-but-wrong count.
A DNS resolver front-end receives a hostname string and must split it into its dot-separated labels (for example www.example.com has 3 labels). The asset here is your parser's control flow: an attacker who submits a crafted hostname can exploit sloppy label counting to smuggle malformed names past validation, cause off-by-one indexing, or trigger empty-label confusion that later code treats as a wildcard.
The insecure assumption is that any non-empty string is a well-formed hostname. It is not. A leading dot (.a.b), a trailing dot (a.b.), or a double dot (a..b) all encode an EMPTY label, which is invalid in a hostname. Deny by default: reject anything malformed instead of guessing a count.
Implement int count_labels(const char *h) that returns the number of dot-separated labels in h, or -1 if h is NULL, empty, or contains any empty label. Operate only on the caller-provided buffer; never assume it is well-formed and always check before you index.
count_labels(three) where three = "a.b.c" -> 3count_labels(NULL) -> -1count_labels(trailing) where trailing = "a.b." -> -1A single argument: const char *h, a NUL-terminated hostname string, or NULL. The harness passes fixed strings baked into the test buffer.
An int: the count of dot-separated labels (>= 1) for a valid hostname, or -1 for NULL, empty, or any input containing an empty label.
C11, no dynamic allocation. Do not read past the NUL terminator. Do not modify the input buffer. Treat h as untrusted: validate before counting. A valid hostname has at least one label and no empty labels.
int count_labels(const char *h){
/* TODO: implement label counting with validation.
Return the number of dot-separated labels in h, or -1 if h is
NULL/empty or contains any empty label (leading/trailing/double dot).
This stub is intentionally wrong and must be replaced. */
(void)h;
return 0;
}Counting dots and adding 1 without checking for empty labels (so "a..b" wrongly returns 3). Forgetting the trailing-dot case because the loop ends before validating the final label. Returning 0 or 1 for NULL/empty instead of -1. Using strtok, which mutates the input and silently collapses consecutive delimiters, hiding the malformed input you are supposed to reject.
NULL pointer -> -1. Empty string "" -> -1. Single label "example" -> 1. Leading dot ".a.b" -> -1. Trailing dot "a.b." -> -1. Double dot "a..b" -> -1. Lone dot "." -> -1. A long single label with no dots -> 1.
Solve this exercise in the browser editor — compile and run against the test harness, no setup required.