/* Reading and writing - assuming little endian in the file */
/* --------------------------------------------------------------------- */
+static void *x3f_limited_malloc(UINT64 sz)
+{
+ if (sz > LIBRAW_X3F_ALLOC_LIMIT_MB * 1024ULL * 1024ULL)
+ throw LIBRAW_EXCEPTION_TOOBIG;
+ void *ret = malloc(sz);
+ if (!ret)
+ throw LIBRAW_EXCEPTION_ALLOC;
+ return ret;
+}
+
+static void *x3f_limited_calloc(UINT64 n, UINT64 sz)
+{
+ if (sz * n > LIBRAW_X3F_ALLOC_LIMIT_MB * 1024ULL * 1024ULL)
+ throw LIBRAW_EXCEPTION_TOOBIG;
+ void *ret = calloc(n, sz);
+ if (!ret)
+ throw LIBRAW_EXCEPTION_ALLOC;
+ return ret;
+}
+
+static void *x3f_limited_realloc(void *ptr, UINT64 sz)
+{
+ if (sz > LIBRAW_X3F_ALLOC_LIMIT_MB * 1024ULL * 1024ULL)
+ throw LIBRAW_EXCEPTION_TOOBIG;
+ void *ret = realloc(ptr, sz);
+ if (!ret)
+ throw LIBRAW_EXCEPTION_ALLOC;
+ return ret;
+}
+
+
static int x3f_get1(LibRaw_abstract_datastream *f)
{
/* Little endian file */
int _i; \
(_T).size = (_NUM); \
(_T).element = \
- (_TYPE *)realloc((_T).element, (_NUM) * sizeof((_T).element[0])); \
+ (_TYPE *)x3f_limited_realloc((_T).element, (_NUM) * sizeof((_T).element[0])); \
for (_i = 0; _i < (int)(_T).size; _i++) \
_GETX((_T).element[_i]); \
} while (0)
{ \
int _i; \
(_T).size = (_NUM); \
- (_T).element = (x3f_property_t *)realloc( \
+ (_T).element = (x3f_property_t *)x3f_limited_realloc( \
(_T).element, (_NUM) * sizeof((_T).element[0])); \
for (_i = 0; _i < (int)(_T).size; _i++) \
{ \
for (_i = 0;; _i++) \
{ \
(_T).size = _i + 1; \
- (_T).element = (x3f_true_huffman_element_t *)realloc( \
+ (_T).element = (x3f_true_huffman_element_t *)x3f_limited_realloc( \
(_T).element, (_i + 1) * sizeof((_T).element[0])); \
GET1((_T).element[_i].code_size); \
GET1((_T).element[_i].code); \
HTP->free_node_index = 0;
HTP->total_node_index = HUF_TREE_MAX_NODES(leaves);
- HTP->nodes = (x3f_huffnode_t *)calloc(1, HUF_TREE_MAX_NODES(leaves) *
+ HTP->nodes = (x3f_huffnode_t *)x3f_limited_calloc(1, HUF_TREE_MAX_NODES(leaves) *
sizeof(x3f_huffnode_t));
}
static x3f_true_t *new_true(x3f_true_t **TRUP)
{
- x3f_true_t *TRU = (x3f_true_t *)calloc(1, sizeof(x3f_true_t));
+ x3f_true_t *TRU = (x3f_true_t *)x3f_limited_calloc(1, sizeof(x3f_true_t));
cleanup_true(TRUP);
static x3f_quattro_t *new_quattro(x3f_quattro_t **QP)
{
- x3f_quattro_t *Q = (x3f_quattro_t *)calloc(1, sizeof(x3f_quattro_t));
+ x3f_quattro_t *Q = (x3f_quattro_t *)x3f_limited_calloc(1, sizeof(x3f_quattro_t));
int i;
cleanup_quattro(QP);
static x3f_huffman_t *new_huffman(x3f_huffman_t **HUFP)
{
- x3f_huffman_t *HUF = (x3f_huffman_t *)calloc(1, sizeof(x3f_huffman_t));
+ x3f_huffman_t *HUF = (x3f_huffman_t *)x3f_limited_calloc(1, sizeof(x3f_huffman_t));
cleanup_huffman(HUFP);
if (!infile)
return NULL;
INT64 fsize = infile->size();
- x3f_t *x3f = (x3f_t *)calloc(1, sizeof(x3f_t));
- if (!x3f)
- throw LIBRAW_EXCEPTION_ALLOC;
+ x3f_t *x3f = (x3f_t *)x3f_limited_calloc(1, sizeof(x3f_t));
try
{
x3f_info_t *I = NULL;
if (DS->num_directory_entries > 0)
{
size_t size = DS->num_directory_entries * sizeof(x3f_directory_entry_t);
- DS->directory_entry = (x3f_directory_entry_t *)calloc(1, size);
+ DS->directory_entry = (x3f_directory_entry_t *)x3f_limited_calloc(1, size);
}
/* Traverse the directory */
if (fpos + size > I->input.file->size())
throw LIBRAW_EXCEPTION_IO_CORRUPT;
-
- // All known files from real cameras are many times smaller than 1 GB, so the hard limit is OK here.
-
- if(size > 1024*1024*1024)
- throw LIBRAW_EXCEPTION_ALLOC;
-
- *data = (void *)malloc(size);
- if (!*data)
- throw LIBRAW_EXCEPTION_ALLOC;
+
+ *data = (void *)x3f_limited_malloc(size);
GETN(*data, size);
uint32_t columns = Q->plane[0].columns;
uint32_t rows = Q->plane[0].rows;
uint32_t channels = 3;
- uint32_t size = columns * rows * channels;
+ UINT64 size = UINT64(columns) * UINT64(rows) * UINT64(channels);
TRU->x3rgb16.columns = columns;
TRU->x3rgb16.rows = rows;
TRU->x3rgb16.channels = channels;
TRU->x3rgb16.row_stride = columns * channels;
- TRU->x3rgb16.buf = malloc(sizeof(uint16_t) * size);
+ TRU->x3rgb16.buf = x3f_limited_malloc(sizeof(uint16_t) * size);
TRU->x3rgb16.data = (uint16_t *)TRU->x3rgb16.buf;
columns = Q->plane[2].columns;
rows = Q->plane[2].rows;
channels = 1;
- size = columns * rows * channels;
+ size = UINT64(columns) * UINT64(rows) * UINT64(channels);
Q->top16.columns = columns;
Q->top16.rows = rows;
Q->top16.channels = channels;
Q->top16.row_stride = columns * channels;
- Q->top16.buf = malloc(sizeof(uint16_t) * size);
+ Q->top16.buf = x3f_limited_malloc(sizeof(uint16_t) * size);
Q->top16.data = (uint16_t *)Q->top16.buf;
}
else
{
- uint32_t size = ID->columns * ID->rows * 3;
+ UINT64 size = UINT64(ID->columns) * UINT64(ID->rows) * 3ULL;
TRU->x3rgb16.columns = ID->columns;
TRU->x3rgb16.rows = ID->rows;
TRU->x3rgb16.channels = 3;
TRU->x3rgb16.row_stride = ID->columns * 3;
- TRU->x3rgb16.buf = malloc(sizeof(uint16_t) * size);
+ TRU->x3rgb16.buf = x3f_limited_malloc(sizeof(uint16_t) * size);
TRU->x3rgb16.data = (uint16_t *)TRU->x3rgb16.buf;
}
x3f_directory_entry_header_t *DEH = &DE->header;
x3f_image_data_t *ID = &DEH->data_subsection.image_data;
x3f_huffman_t *HUF = new_huffman(&ID->huffman);
- uint32_t size;
+ UINT64 size;
if (use_map_table)
{
{
case X3F_IMAGE_RAW_HUFFMAN_X530:
case X3F_IMAGE_RAW_HUFFMAN_10BIT:
- size = ID->columns * ID->rows * 3;
+ size = UINT64(ID->columns) * UINT64(ID->rows) * 3ULL;
HUF->x3rgb16.columns = ID->columns;
HUF->x3rgb16.rows = ID->rows;
HUF->x3rgb16.channels = 3;
HUF->x3rgb16.row_stride = ID->columns * 3;
- HUF->x3rgb16.buf = malloc(sizeof(uint16_t) * size);
+ HUF->x3rgb16.buf = x3f_limited_malloc(sizeof(uint16_t) * size);
HUF->x3rgb16.data = (uint16_t *)HUF->x3rgb16.buf;
break;
case X3F_IMAGE_THUMB_HUFFMAN:
- size = ID->columns * ID->rows * 3;
+ size = UINT64(ID->columns) * UINT64(ID->rows) * 3ULL;
HUF->rgb8.columns = ID->columns;
HUF->rgb8.rows = ID->rows;
HUF->rgb8.channels = 3;
HUF->rgb8.row_stride = ID->columns * 3;
- HUF->rgb8.buf = malloc(sizeof(uint8_t) * size);
+ HUF->rgb8.buf = x3f_limited_malloc(sizeof(uint8_t) * size);
HUF->rgb8.data = (uint8_t *)HUF->rgb8.buf;
break;
default:
int i;
CAMF->decoded_data_size = CAMF->data_size;
- CAMF->decoded_data = malloc(CAMF->decoded_data_size);
+ CAMF->decoded_data = x3f_limited_malloc(CAMF->decoded_data_size);
for (i = 0; i < (int)CAMF->data_size; i++)
{
CAMF->decoded_data_size = dst_size;
- CAMF->decoded_data = malloc(CAMF->decoded_data_size);
+ CAMF->decoded_data = x3f_limited_malloc(CAMF->decoded_data_size);
memset(CAMF->decoded_data, 0, CAMF->decoded_data_size);
dst = (uint8_t *)CAMF->decoded_data;
for (i = 0, p = (uint8_t *)CAMF->data; *p != 0; i++)
{
/* TODO: Is this too expensive ??*/
- element = (x3f_true_huffman_element_t *)realloc(element,
+ element = (x3f_true_huffman_element_t *)x3f_limited_realloc(element,
(i + 1) * sizeof(*element));
element[i].code_size = *p++;
int32_t i;
CAMF->decoded_data_size = CAMF->t5.decoded_data_size;
- CAMF->decoded_data = malloc(CAMF->decoded_data_size);
+ CAMF->decoded_data = x3f_limited_malloc(CAMF->decoded_data_size);
dst = (uint8_t *)CAMF->decoded_data;
for (i = 0, p = (uint8_t *)CAMF->data; *p != 0; i++)
{
/* TODO: Is this too expensive ??*/
- element = (x3f_true_huffman_element_t *)realloc(element,
+ element = (x3f_true_huffman_element_t *)x3f_limited_realloc(element,
(i + 1) * sizeof(*element));
element[i].code_size = *p++;
uint32_t num = entry->property_num = *(uint32_t *)v;
uint32_t off = *(uint32_t *)(v + 4);
- entry->property_name = (char **)malloc(num * sizeof(uint8_t *));
- entry->property_value = (uint8_t **)malloc(num * sizeof(uint8_t *));
+ entry->property_name = (char **)x3f_limited_malloc(num * sizeof(uint8_t *));
+ entry->property_value = (uint8_t **)x3f_limited_malloc(num * sizeof(uint8_t *));
for (i = 0; i < (int)num; i++)
{
: sizeof(uint32_t)) *
elements;
- entry->matrix_decoded = malloc(size);
+ entry->matrix_decoded = x3f_limited_malloc(size);
switch (element_size)
{
uint32_t dim = entry->matrix_dim = *(uint32_t *)(v + 4);
uint32_t off = entry->matrix_data_off = *(uint32_t *)(v + 8);
camf_dim_entry_t *dentry = entry->matrix_dim_entry =
- (camf_dim_entry_t *)malloc(dim * sizeof(camf_dim_entry_t));
+ (camf_dim_entry_t *)x3f_limited_malloc(dim * sizeof(camf_dim_entry_t));
for (i = 0; i < (int)dim; i++)
{
}
/* TODO: lots of realloc - may be inefficient */
- entry = (camf_entry_t *)realloc(entry, (i + 1) * sizeof(camf_entry_t));
+ entry = (camf_entry_t *)x3f_limited_realloc(entry, (i + 1) * sizeof(camf_entry_t));
/* Pointer */
entry[i].entry = p;