/* DF-1696: mpssas_evt_handler u16 truncation.
 *   u16 sz; sz = le16toh(event->EventDataLength) * 4;
 * For EventDataLength >= 0x4000, sz wraps. For 0x4000 -> sz=0 -> kmalloc(0)
 * returns ZERO_LENGTH_PTR (-8) -> first deref near-NULL -> fatal page fault.
 * For 0x4001..0x7FFF sz wraps to 4..65532 -> undersized alloc, struct access OOB.
 */
#include <stdio.h>
#include <stdint.h>

static int fixed = 0;

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

    /* simulate EventDataLength values that wrap u16 */
    uint16_t test_lengths[] = { 0x4000, 0x4001, 0x6000, 0x7FFF };
    for (int i = 0; i < 4; i++) {
        uint16_t edl = test_lengths[i];
        if (fixed) {
            uint32_t sz = (uint32_t)edl * 4;
            if (sz == 0 || sz > 65536) sz = 65536;
            printf("EventDataLength=0x%x -> patched sz=%u\n", edl, sz);
        } else {
            uint16_t sz = edl * 4;  /* truncates! */
            printf("EventDataLength=0x%x -> buggy sz=%u (truncated)\n", edl, sz);
        }
    }
    printf("RESULT: %s\n", fixed ? "PATCHED - u32 sz, sanity check" : "BUGGY - u16 truncation");
    return 0;
}
