/* DF-1702: scmouse mouse_cut heap overflow.
 * cut_buffer_size = xsize*ysize + 1 (e.g., 80*25+1 = 2001).
 * Full-screen selection over non-space:
 *   per line (ysize lines): xsize cell bytes + 1 '\r' = xsize+1 bytes
 *   total = (xsize+1)*ysize, then +1 NUL = (xsize+1)*ysize + 1.
 * Buffer overflows by ysize-1 bytes + NUL.
 */
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

static int fixed = 0;

int main(int argc, char **argv) {
    if (argc > 1 && !strcmp(argv[1], "--fixed")) fixed = 1;

    int xsize = 80, ysize = 25;
    int alloc_size;
    if (fixed) alloc_size = (xsize + 1) * ysize + 1;
    else       alloc_size = xsize * ysize + 1;

    char *cut_buffer = calloc(1, alloc_size);

    /* simulate full-screen selection over non-space */
    int i = 0, blank = 0;
    int overflow_at = -1;
    for (int p_line_start = 0; p_line_start < xsize*ysize; p_line_start += xsize) {
        for (int p = p_line_start; p < p_line_start + xsize; p++) {
            if (i >= alloc_size) { overflow_at = i; goto done; }
            cut_buffer[i++] = 'X';
            blank = i;  /* non-space */
        }
        /* at line end: cut_buffer[blank] = '\r'; i = blank+1 */
        if (blank >= alloc_size) { overflow_at = blank; goto done; }
        cut_buffer[blank] = '\r';
        i = blank + 1;
    }
    /* final NUL */
    if (i >= alloc_size) { overflow_at = i; goto done; }
    cut_buffer[i] = '\0';
done:
    if (overflow_at >= 0) {
        printf("OVERFLOW at index %d (buffer=%d)\n", overflow_at, alloc_size);
        printf("RESULT: BUGGY - heap overflow by %d bytes\n",
               (xsize+1)*ysize + 1 - alloc_size);
    } else {
        printf("final index=%d (buffer=%d) - fits\n", i, alloc_size);
        printf("RESULT: PATCHED - no overflow\n");
    }
    free(cut_buffer);
    return 0;
}
