Skip to content

Commit 22da560

Browse files
committed
fix overflow issue in buffer allocation
1 parent 436d5a4 commit 22da560

3 files changed

Lines changed: 28 additions & 2 deletions

File tree

src/cgif.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ 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
77+
// width or height cannot be zero
7878
if(!pConfig->width || !pConfig->height) {
7979
return NULL;
8080
}

src/cgif_raw.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <stdlib.h>
22
#include <string.h>
3+
#include <stdint.h>
34

45
#include "cgif_raw.h"
56

@@ -330,7 +331,15 @@ static int LZW_GenerateStream(LZWResult* pResult, const uint32_t numPixel, const
330331
// where N = max dictionary resets = numPixel / (MAX_DICT_LEN - initDictLen - 2)
331332
entriesPerCycle = MAX_DICT_LEN - initDictLen - 2; // maximum added number of dictionary entries per cycle: -2 to account for start and end code
332333
maxResets = numPixel / entriesPerCycle;
333-
pContext->pLZWData = malloc(sizeof(uint16_t) * ((size_t)numPixel + 2 + maxResets));
334+
335+
// check for integer overflow in dictArraySize calculation and malloc
336+
if (numPixel > (SIZE_MAX - 2 - maxResets) || ((size_t)numPixel + 2 + maxResets) > (SIZE_MAX / sizeof(uint16_t))) {
337+
r = CGIF_EALLOC;
338+
goto LZWGENERATE_Cleanup;
339+
}
340+
const size_t dictArraySize = (size_t)numPixel + 2 + maxResets;
341+
pContext->pLZWData = malloc(sizeof(uint16_t) * dictArraySize);
342+
334343
if(pContext->pLZWData == NULL) {
335344
r = CGIF_EALLOC;
336345
goto LZWGENERATE_Cleanup;
@@ -454,6 +463,12 @@ CGIFRaw* cgif_raw_newgif(const CGIFRaw_Config* pConfig) {
454463
uint8_t aHeader[SIZE_MAIN_HEADER];
455464
CGIFRaw* pGIF;
456465
int rWrite;
466+
467+
// width or height cannot be zero
468+
if(!pConfig->width || !pConfig->height) {
469+
return NULL;
470+
}
471+
457472
// check for invalid GCT size
458473
if(pConfig->sizeGCT > 256) {
459474
return NULL; // invalid GCT size
@@ -503,6 +518,12 @@ cgif_result cgif_raw_addframe(CGIFRaw* pGIF, const CGIFRaw_FrameConfig* pConfig)
503518
LZWResult encResult;
504519
int r, rWrite;
505520
const int useLCT = pConfig->sizeLCT; // LCT stands for "local color table"
521+
522+
// width or height cannot be zero
523+
if(!pConfig->width || !pConfig->height) {
524+
pGIF->curResult = CGIF_ERROR;
525+
return pGIF->curResult;
526+
}
506527
const int isInterlaced = (pConfig->attrFlags & CGIF_RAW_FRAME_ATTR_INTERLACED) ? 1 : 0;
507528
uint16_t numEffColors; // number of effective colors
508529
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)