tiles.init(ifd, imgdata.sizes, libraw_internal_data.unpacker_data, libraw_internal_data.unpacker_data.order,
libraw_internal_data.internal_data.input);
+ // Max bytes: 2^16 raw width * 2^2 bytes/pixel * 2^2 channels = 2^20, so check against 2^22
+ INT64 rowbytes = INT64(MAX(tiles.tileWidth, imgdata.sizes.raw_width)) * INT64(MAX(bytesps,4)) * INT64(ifd->samples);
+ if(rowbytes > (1LL << 22))
+ throw LIBRAW_EXCEPTION_TOOBIG;
+
INT64 allocsz = INT64(tiles.tileCnt) * INT64(tiles.tileWidth) * INT64(tiles.tileHeight) * INT64(ifd->samples) * INT64(sizeof(float));
if (allocsz > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024))
throw LIBRAW_EXCEPTION_TOOBIG;
if (ifd->sample_format == 3)
- float_raw_image = (float *)calloc(tiles.tileCnt * tiles.tileWidth * tiles.tileHeight *ifd->samples, sizeof(float));
+ float_raw_image = (float *)calloc(allocsz,1);
else
throw LIBRAW_EXCEPTION_DECODE_RAW; // Only float supported
size_t rowsInTile = y + tiles.tileHeight > imgdata.sizes.raw_height ? imgdata.sizes.raw_height - y : tiles.tileHeight;
size_t colsInTile = x + tiles.tileWidth > imgdata.sizes.raw_width ? imgdata.sizes.raw_width - x : tiles.tileWidth;
+ // inrowbytes is less then 2^22 (see above) so conversion to int is safe
size_t inrowbytes = colsInTile * bytesps * ifd->samples;
int fullrowbytes = tiles.tileWidth *bytesps * ifd->samples;
size_t outrowbytes = colsInTile * sizeof(float) * ifd->samples;
unsigned char *dst = fullrowbytes > inrowbytes ? rowbuf.data(): // last tile in row, use buffer
(unsigned char *)&float_raw_image
[((y + row) * imgdata.sizes.raw_width + x) * ifd->samples];
- libraw_internal_data.internal_data.input->read(dst, 1, fullrowbytes);
+ int bytesread = libraw_internal_data.internal_data.input->read(dst, 1, fullrowbytes);
+ if (bytesread < fullrowbytes)
+ derror();
if (bytesps == 2 && difford)
libraw_swab(dst, fullrowbytes);
else if (bytesps == 3 && (libraw_internal_data.unpacker_data.order == 0x4949)) // II-16bit