cybersecurity · intermediate · ~15 min · safe pentest lab

Replace unsafe strcpy with bounded copy

Apply the bounded-copy pattern as a focused refactor.

Challenge

Refactor the textbook buffer-overflow bug below into a bounded version that can never write past the destination.

The original has the classic flaw — it copies into out with no idea how big out is:

void greet(char *out, const char *name) {
    strcpy(out, "Hello, ");
    strcat(out, name);   // unbounded — overflows out
}

Task

Implement int greet(char *out, size_t out_sz, const char *name) that writes "Hello, <name>" into out without ever overflowing it.

Input

  • out: the destination buffer.
  • out_sz: the size of out in bytes.
  • name: a NUL-terminated string the grader passes (e.g. "Ada", "").

Output

Returns 0 on success, with out holding "Hello, <name>". Returns -1 if the full result would not fit in out_sz bytes. out is always left NUL-terminated.

Example

greet(buf, 16, "Ada")              ->   0,  buf = "Hello, Ada"
greet(buf, 16, "")                 ->   0,  buf = "Hello, "
greet(buf, 10, "Very Long Name")   ->   -1, buf NUL-terminated

Edge cases

  • Empty name: succeeds, producing "Hello, ".
  • Result one byte too long: return -1, leave out NUL-terminated.
  • out_sz == 0: return -1.

Rules

  • Use a bounded write (e.g. snprintf) and detect truncation via its return value.

Input format

A destination buffer out, its size out_sz, and a NUL-terminated name.

Output format

0 on success (out = "Hello, "); -1 if the result would overflow. out is always NUL-terminated.

Constraints

Never write past out_sz; always NUL-terminate; detect truncation.

Starter code

#include <stdio.h>
#include <string.h>

int greet(char *out, size_t out_sz, const char *name) {
    /* TODO: build "Hello, <name>" safely */
    return -1;
}

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