linux-sysprog · intermediate · ~15 min

Read an integer environment variable with bounds

Parse-and-validate-then-use, with explicit range bounds.

Challenge

Parse an integer from an environment-variable value string and accept it only if it is well-formed and within an allowed range — the way hardened code treats untrusted config.

Task

Implement int env_int_in_range(const char *getval, int lo, int hi, int *out) that strictly parses getval and range-checks it.

Input

  • getval: the variable's value as a string (the grader passes the raw string directly, including NULL or junk). A valid value is an optional leading - followed by digits, with no trailing characters.
  • lo, hi: the inclusive allowed range.
  • out: where to store the parsed value on success.

Output

On success, stores the parsed integer in *out and returns 0. Returns -1 if getval is NULL or empty, fails to parse, has trailing garbage, or falls outside [lo, hi].

Example

env_int_in_range("8080", 1, 65535, &out)   ->   0, out = 8080
env_int_in_range("0", 1, 65535, &out)      ->   -1   (below lo)
env_int_in_range("99999", 1, 65535, &out)  ->   -1   (above hi)
env_int_in_range("8080x", 1, 65535, &out)  ->   -1   (trailing garbage)
env_int_in_range("-5", -10, 10, &out)      ->   0, out = -5
env_int_in_range(NULL, 1, 65535, &out)     ->   -1
env_int_in_range("", 1, 65535, &out)       ->   -1

Edge cases

  • NULL or empty string: -1.
  • Negative numbers and a single-value range (lo == hi) are allowed when in range.
  • Any non-digit trailing character makes the whole string invalid.

Why this matters

Environment variables are attacker-influenceable in many deployment contexts (containers, init systems, CI). Treating them as untrusted input and validating both the format and the value range is one of the easiest hardening wins.

Input format

A value string getval (may be NULL or junk), inclusive bounds lo/hi, and an out pointer for the result.

Output format

Stores the parsed int in *out and returns 0 on success; returns -1 on NULL/empty/parse-failure/out-of-range.

Constraints

Use strtol and require *endptr == '\0' (no trailing garbage). Reject NULL/empty before parsing.

Starter code

int env_int_in_range(const char *getval, int lo, int hi, int *out) { /* TODO */ return -1; }

Common mistakes

Using atoi — no error reporting. Forgetting to check *endptr == '\0'. Allowing whitespace, which is friendly but ambiguous.

Edge cases to handle

NULL; empty; negative numbers; leading + sign; overflow of long.

Complexity

O(strlen).

Background lessons

Up next

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