The idea: strings carry a hidden byte
A C string of n characters occupies n + 1 bytes. The last one is the terminating '\0'. strlen does not count it, and malloc does not add it for you.
Writing one byte past the end of a block is a heap buffer overflow. It often "works": the byte lands in padding, the tests stay green, and the corruption waits for a bad day.
The situation
upper_copy returns an upper-cased copy of a string. Run the tests: they pass. Now run the sanitizer: it does not.
Your mission
Read the sanitizer report: it names the block that was overrun, the line where it was allocated, and the function that wrote past its end. Compare how many bytes are allocated with how many bytes are written. Then give the junior the exact arithmetic.
What to watch for
- Passing tests prove nothing about memory safety. Both tools must come back clean.
- "Allocate more" is tempting. Does it hold for every length? Think about the empty string.