Untitled

 avatar
unknown
plain_text
10 months ago
1.9 kB
16
Indexable
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#ifdef _WIN32
  #include <io.h>
  #define READ _read
#else
  #include <unistd.h>
  #define READ read
#endif

#define MAX_SIZE 128

int main(void) {
    char buf[64];
    char in[MAX_SIZE];
    size_t safe_bytes = 0;   /* final, validated copy length */
    size_t inlen = 0;

    /* ---- Read input safely and terminate ---- */
    printf("Enter buffer contents:\n");
    ssize_t got = READ(0, in, MAX_SIZE - 1);
    if (got < 0) {
        perror("read");
        return 1;
    }
    in[got] = '\0';

    /* ---- Ask user how many bytes (may be unsafe/tainted) ---- */
    printf("Bytes to copy:\n");
    unsigned long tmp = 0;
    if (scanf("%lu", &tmp) != 1) {
        fprintf(stderr, "Invalid number; defaulting to 0\n");
        tmp = 0;
    }

    /* ---- Compute a SAFE, non-tainted length ----
       We only trust the user value if it’s within BOTH bounds:
       (1) available input length, (2) destination capacity - 1 (for NUL).
       Otherwise we fall back to the strict safe cap. */
    inlen = strnlen(in, MAX_SIZE);
    if (tmp <= inlen && tmp <= sizeof(buf) - 1) {
        safe_bytes = (size_t)tmp;
    } else {
        /* fallback: safest possible bounded copy */
        safe_bytes = inlen;
        if (safe_bytes > sizeof(buf) - 1) {
            safe_bytes = sizeof(buf) - 1;
        }
    }

    /* ---- Copy with bounds checking and NUL-termination ---- */
#ifdef _WIN32
    /* MSVC’s checked runtime helps Fortify see the guard explicitly */
    if (memcpy_s(buf, sizeof buf, in, safe_bytes) != 0) {
        fprintf(stderr, "memcpy_s failed\n");
        return 1;
    }
#else
    memcpy(buf, in, safe_bytes);
#endif
    buf[safe_bytes] = '\0';

    /* Optional: show result */
    printf("Copied (%zu bytes): \"%s\"\n", safe_bytes, buf);
    return 0;
}
Editor is loading...
Leave a Comment