Skip to content

Commit 2ea2d76

Browse files
committed
fix overflow in allocation
1 parent 436d5a4 commit 2ea2d76

3 files changed

Lines changed: 25 additions & 2 deletions

File tree

src/cgif.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ CGIF* cgif_newgif(CGIF_Config* pConfig) {
7474
CGIF* pGIF;
7575
CGIFRaw* pGIFRaw; // raw GIF stream
7676
CGIFRaw_Config rawConfig = {0};
77-
// width or heigth cannot be zero
7877
if(!pConfig->width || !pConfig->height) {
7978
return NULL;
8079
}

src/cgif_raw.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,14 @@ static int LZW_GenerateStream(LZWResult* pResult, const uint32_t numPixel, const
330330
// where N = max dictionary resets = numPixel / (MAX_DICT_LEN - initDictLen - 2)
331331
entriesPerCycle = MAX_DICT_LEN - initDictLen - 2; // maximum added number of dictionary entries per cycle: -2 to account for start and end code
332332
maxResets = numPixel / entriesPerCycle;
333-
pContext->pLZWData = malloc(sizeof(uint16_t) * ((size_t)numPixel + 2 + maxResets));
333+
334+
// check for integer overflow in dictArraySize calculation and malloc
335+
if (numPixel > (SIZE_MAX - 2 - maxResets) || ((size_t)numPixel + 2 + maxResets) > (SIZE_MAX / sizeof(uint16_t))) {
336+
r = CGIF_EALLOC;
337+
goto LZWGENERATE_Cleanup;
338+
}
339+
const size_t dictArraySize = (size_t)numPixel + 2 + maxResets;
340+
pContext->pLZWData = malloc(sizeof(uint16_t) * dictArraySize);
334341
if(pContext->pLZWData == NULL) {
335342
r = CGIF_EALLOC;
336343
goto LZWGENERATE_Cleanup;
@@ -454,6 +461,12 @@ CGIFRaw* cgif_raw_newgif(const CGIFRaw_Config* pConfig) {
454461
uint8_t aHeader[SIZE_MAIN_HEADER];
455462
CGIFRaw* pGIF;
456463
int rWrite;
464+
465+
// width or height cannot be zero
466+
if(!pConfig->width || !pConfig->height) {
467+
return NULL;
468+
}
469+
457470
// check for invalid GCT size
458471
if(pConfig->sizeGCT > 256) {
459472
return NULL; // invalid GCT size
@@ -503,6 +516,12 @@ cgif_result cgif_raw_addframe(CGIFRaw* pGIF, const CGIFRaw_FrameConfig* pConfig)
503516
LZWResult encResult;
504517
int r, rWrite;
505518
const int useLCT = pConfig->sizeLCT; // LCT stands for "local color table"
519+
520+
// width or height cannot be zero
521+
if(!pConfig->width || !pConfig->height) {
522+
pGIF->curResult = CGIF_ERROR;
523+
return pGIF->curResult;
524+
}
506525
const int isInterlaced = (pConfig->attrFlags & CGIF_RAW_FRAME_ATTR_INTERLACED) ? 1 : 0;
507526
uint16_t numEffColors; // number of effective colors
508527
uint16_t initDictLen;

src/cgif_rgb.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,11 @@ static int quantize_and_dither(colHashTable* colhash, const uint8_t* pImageDataR
542542
if(root == NULL) {
543543
return -1;
544544
}
545+
// check for integer overflow in malloc
546+
if (numPixel > (SIZE_MAX / (fmtChan * sizeof(float)))) {
547+
free_decision_tree(root);
548+
return -1;
549+
}
545550
float* pImageDataRGBfloat = malloc(fmtChan * numPixel * sizeof(float)); // TBD fmtChan + only when hasAlpha
546551
if(pImageDataRGBfloat == NULL) {
547552
free_decision_tree(root);

0 commit comments

Comments
 (0)