Esme Povirk (@madewokherd) commented about dlls/sane.ds/ds_image.c:
struct read_data_params params = { NULL, activeDS.frame_params.bytes_per_line, &retlen };if (y >= -header->biHeight){TRACE("Data source transfers more lines than expected. Extend DIB to %ld lines\n", (-header->biHeight)+1000);GlobalUnlock(hDIB);dib_bytes += 1000 * dib_bytes_per_line;hDIB = GlobalReAlloc(hDIB, dib_bytes + sizeof(*header) + color_size, GMEM_MOVEABLE);if (!hDIB){SANE_Cancel();activeDS.twCC = TWCC_LOWMEMORY;activeDS.currentState = 6;return TWRC_FAILURE;
hDIB needs to be freed in this case, but we lost its value by assigning from GlobalReAlloc. With GMEM_MOVEABLE, that assignment isn't necessary, so we could just do a check here like `if (!GlobalReAlloc(...))`.