added memory allocation checks (fixes issue 355)

This commit is contained in:
Antonin Descampe 2014-09-19 10:26:35 +00:00
parent b9a247b559
commit 6868ee373e
11 changed files with 162 additions and 61 deletions

View File

@ -571,6 +571,7 @@ OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1D
h.mem = (OPJ_INT32*)
opj_aligned_malloc(opj_dwt_max_resolution(tr, numres) * sizeof(OPJ_INT32));
if (! h.mem){
/* FIXME event manager error callback */
return OPJ_FALSE;
}
@ -842,6 +843,10 @@ OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numr
OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0);
h.wavelet = (opj_v4_t*) opj_aligned_malloc((opj_dwt_max_resolution(res, numres)+5) * sizeof(opj_v4_t));
if (!h.wavelet) {
/* FIXME event manager error callback */
return OPJ_FALSE;
}
v.wavelet = h.wavelet;
while( --numres) {

View File

@ -4120,6 +4120,10 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
(opj_tp_index_t*)opj_calloc(l_num_parts, sizeof(opj_tp_index_t));
if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read SOT marker. Tile index allocation failed\n");
return OPJ_FALSE;
}
}
else {
opj_tp_index_t *new_tp_index = (opj_tp_index_t *) opj_realloc(
@ -4127,7 +4131,7 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
if (! new_tp_index) {
opj_free(p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index);
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = NULL;
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read SOT marker. Tile index allocation failed\n");
return OPJ_FALSE;
}
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = new_tp_index;
@ -4141,6 +4145,11 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index =
(opj_tp_index_t*)opj_calloc( p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps,
sizeof(opj_tp_index_t));
if (!p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index) {
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 0;
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read SOT marker. Tile index allocation failed\n");
return OPJ_FALSE;
}
}
if ( l_current_part >= p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps ){
@ -4153,7 +4162,7 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k,
opj_free(p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index);
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = NULL;
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = 0;
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n");
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read SOT marker. Tile index allocation failed\n");
return OPJ_FALSE;
}
p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index = new_tp_index;
@ -6096,7 +6105,7 @@ OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_UINT16 rsiz, opj_ev
return OPJ_TRUE;
}
void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
OPJ_BOOL opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
opj_cparameters_t *parameters,
opj_image_t *image,
opj_event_mgr_t * p_manager)
@ -6105,7 +6114,7 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
opj_cp_t *cp = 00;
if(!p_j2k || !parameters || ! image) {
return;
return OPJ_FALSE;
}
/* keep a link to cp so that we can destroy it later in j2k_destroy_compress */
@ -6115,22 +6124,6 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
cp->tw = 1;
cp->th = 1;
/* Create comment for codestream */
if(parameters->cp_comment == NULL) {
const char comment[] = "Created by OpenJPEG version ";
const size_t clen = strlen(comment);
const char *version = opj_version();
/* UniPG>> */
#ifdef USE_JPWL
parameters->cp_comment = (char*)opj_malloc(clen+strlen(version)+11);
sprintf(parameters->cp_comment,"%s%s with JPWL", comment, version);
#else
parameters->cp_comment = (char*)opj_malloc(clen+strlen(version)+1);
sprintf(parameters->cp_comment,"%s%s", comment, version);
#endif
/* <<UniPG */
}
/* FIXME ADE: to be removed once deprecated cp_cinema and cp_rsiz have been removed */
if (parameters->rsiz == OPJ_PROFILE_NONE) { /* consider deprecated fields only if RSIZ has not been set */
OPJ_BOOL deprecated_used = OPJ_FALSE;
@ -6263,6 +6256,10 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
if (parameters->cp_fixed_alloc && parameters->cp_matrice) {
size_t array_size = (size_t)parameters->tcp_numlayers * (size_t)parameters->numresolution * 3 * sizeof(OPJ_INT32);
cp->m_specific_param.m_enc.m_matrice = (OPJ_INT32 *) opj_malloc(array_size);
if (!cp->m_specific_param.m_enc.m_matrice) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate copy of user encoding parameters matrix \n");
return OPJ_FALSE;
}
memcpy(cp->m_specific_param.m_enc.m_matrice, parameters->cp_matrice, array_size);
}
@ -6276,10 +6273,35 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
/* comment string */
if(parameters->cp_comment) {
cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1);
if(cp->comment) {
strcpy(cp->comment, parameters->cp_comment);
cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1U);
if(!cp->comment) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate copy of comment string\n");
return OPJ_FALSE;
}
strcpy(cp->comment, parameters->cp_comment);
} else {
/* Create default comment for codestream */
const char comment[] = "Created by OpenJPEG version ";
const size_t clen = strlen(comment);
const char *version = opj_version();
/* UniPG>> */
#ifdef USE_JPWL
cp->comment = (char*)opj_malloc(clen+strlen(version)+11);
if(!cp->comment) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate comment string\n");
return OPJ_FALSE;
}
sprintf(cp->comment,"%s%s with JPWL", comment, version);
#else
cp->comment = (char*)opj_malloc(clen+strlen(version)+1);
if(!cp->comment) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate comment string\n");
return OPJ_FALSE;
}
sprintf(cp->comment,"%s%s", comment, version);
#endif
/* <<UniPG */
}
/*
@ -6358,6 +6380,10 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
/* initialize the mutiple tiles */
/* ---------------------------- */
cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t));
if (!cp->tcps) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate tile coding parameters\n");
return OPJ_FALSE;
}
if (parameters->numpocs) {
/* initialisation of POC */
opj_j2k_check_poc_val(parameters->POC,parameters->numpocs, (OPJ_UINT32)parameters->numresolution, image->numcomps, (OPJ_UINT32)parameters->tcp_numlayers, p_manager);
@ -6415,24 +6441,54 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
}
tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t));
if (!tcp->tccps) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate tile component coding parameters\n");
return OPJ_FALSE;
}
if (parameters->mct_data) {
OPJ_UINT32 lMctSize = image->numcomps * image->numcomps * (OPJ_UINT32)sizeof(OPJ_FLOAT32);
OPJ_FLOAT32 * lTmpBuf = (OPJ_FLOAT32*)opj_malloc(lMctSize);
OPJ_INT32 * l_dc_shift = (OPJ_INT32 *) ((OPJ_BYTE *) parameters->mct_data + lMctSize);
if (!lTmpBuf) {
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate temp buffer\n");
return OPJ_FALSE;
}
tcp->mct = 2;
tcp->m_mct_coding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
if (! tcp->m_mct_coding_matrix) {
opj_free(lTmpBuf);
lTmpBuf = NULL;
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate encoder MCT coding matrix \n");
return OPJ_FALSE;
}
memcpy(tcp->m_mct_coding_matrix,parameters->mct_data,lMctSize);
memcpy(lTmpBuf,parameters->mct_data,lMctSize);
tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(lMctSize);
assert(opj_matrix_inversion_f(lTmpBuf,(tcp->m_mct_decoding_matrix),image->numcomps));
if (! tcp->m_mct_decoding_matrix) {
opj_free(lTmpBuf);
lTmpBuf = NULL;
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate encoder MCT decoding matrix \n");
return OPJ_FALSE;
}
if(opj_matrix_inversion_f(lTmpBuf,(tcp->m_mct_decoding_matrix),image->numcomps) == OPJ_FALSE) {
opj_free(lTmpBuf);
lTmpBuf = NULL;
opj_event_msg(p_manager, EVT_ERROR, "Failed to inverse encoder MCT decoding matrix \n");
return OPJ_FALSE;
}
tcp->mct_norms = (OPJ_FLOAT64*)
opj_malloc(image->numcomps * sizeof(OPJ_FLOAT64));
if (! tcp->mct_norms) {
opj_free(lTmpBuf);
lTmpBuf = NULL;
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to allocate encoder MCT norms \n");
return OPJ_FALSE;
}
opj_calculate_norms(tcp->mct_norms,image->numcomps,tcp->m_mct_decoding_matrix);
opj_free(lTmpBuf);
@ -6441,7 +6497,11 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
tccp->m_dc_level_shift = l_dc_shift[i];
}
opj_j2k_setup_mct_encoding(tcp,image);
if (opj_j2k_setup_mct_encoding(tcp,image) == OPJ_FALSE) {
/* free will be handled by opj_j2k_destroy */
opj_event_msg(p_manager, EVT_ERROR, "Failed to setup j2k mct encoding\n");
return OPJ_FALSE;
}
}
else {
if(tcp->mct==1 && image->numcomps == 3) { // RGB->YCC MCT is enabled
@ -6539,6 +6599,7 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
opj_free(parameters->mct_data);
parameters->mct_data = 00;
}
return OPJ_TRUE;
}
static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index, OPJ_UINT32 type, OPJ_OFF_T pos, OPJ_UINT32 len)
@ -8236,16 +8297,11 @@ opj_j2k_t* opj_j2k_create_decompress(void)
/* codestream index creation */
l_j2k->cstr_index = opj_j2k_create_cstr_index();
/*(opj_codestream_index_t*) opj_malloc(sizeof(opj_codestream_index_t));
if (!l_j2k->cstr_index){
opj_j2k_destroy(l_j2k);
return NULL;
return 00;
}
l_j2k->cstr_index->marker = (opj_marker_info_t*) opj_malloc(100 * sizeof(opj_marker_info_t));
*/
/* validation list creation */
l_j2k->m_validation_list = opj_procedure_list_create();
if (! l_j2k->m_validation_list) {
@ -9660,6 +9716,10 @@ OPJ_BOOL opj_j2k_start_compress(opj_j2k_t *p_j2k,
assert(p_manager != 00);
p_j2k->m_private_image = opj_image_create0();
if (! p_j2k->m_private_image) {
opj_event_msg(p_manager, EVT_ERROR, "Failed to allocate image header." );
return OPJ_FALSE;
}
opj_copy_image_header(p_image, p_j2k->m_private_image);
/* TODO_MSD: Find a better way */

View File

@ -594,7 +594,7 @@ void opj_j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters);
opj_j2k_t* opj_j2k_create_compress(void);
void opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
OPJ_BOOL opj_j2k_setup_encoder( opj_j2k_t *p_j2k,
opj_cparameters_t *parameters,
opj_image_t *image,
opj_event_mgr_t * p_manager);

View File

@ -855,7 +855,11 @@ void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
old_comps = image->comps;
new_comps = (opj_image_comp_t*)
opj_malloc(nr_channels * sizeof(opj_image_comp_t));
if (!new_comps) {
/* FIXME no error code for opj_jp2_apply_pclr */
/* FIXME event manager error callback */
return;
}
for(i = 0; i < nr_channels; ++i) {
pcol = cmap[i].pcol; cmp = cmap[i].cmp;
@ -871,6 +875,13 @@ void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color)
/* Palette mapping: */
new_comps[i].data = (OPJ_INT32*)
opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32));
if (!new_comps[i].data) {
opj_free(new_comps);
new_comps = NULL;
/* FIXME no error code for opj_jp2_apply_pclr */
/* FIXME event manager error callback */
return;
}
new_comps[i].prec = channel_size[i];
new_comps[i].sgnd = channel_sign[i];
}
@ -1560,7 +1571,7 @@ void opj_jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters)
/* JP2 encoder interface */
/* ----------------------------------------------------------------------- */
void opj_jp2_setup_encoder( opj_jp2_t *jp2,
OPJ_BOOL opj_jp2_setup_encoder( opj_jp2_t *jp2,
opj_cparameters_t *parameters,
opj_image_t *image,
opj_event_mgr_t * p_manager)
@ -1570,7 +1581,7 @@ void opj_jp2_setup_encoder( opj_jp2_t *jp2,
OPJ_UINT32 sign;
if(!jp2 || !parameters || !image)
return;
return OPJ_FALSE;
/* setup the J2K codec */
/* ------------------- */
@ -1578,10 +1589,12 @@ void opj_jp2_setup_encoder( opj_jp2_t *jp2,
/* Check if number of components respects standard */
if (image->numcomps < 1 || image->numcomps > 16384) {
opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n");
return;
return OPJ_FALSE;
}
opj_j2k_setup_encoder(jp2->j2k, parameters, image, p_manager );
if (opj_j2k_setup_encoder(jp2->j2k, parameters, image, p_manager ) == OPJ_FALSE) {
return OPJ_FALSE;
}
/* setup the JP2 codec */
/* ------------------- */
@ -1595,7 +1608,7 @@ void opj_jp2_setup_encoder( opj_jp2_t *jp2,
if (!jp2->cl){
jp2->cl = NULL;
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
return;
return OPJ_FALSE;
}
jp2->cl[0] = JP2_JP2; /* CL0 : JP2 */
@ -1606,7 +1619,8 @@ void opj_jp2_setup_encoder( opj_jp2_t *jp2,
if (!jp2->comps) {
jp2->comps = NULL;
opj_event_msg(p_manager, EVT_ERROR, "Not enough memory when setup the JP2 encoder\n");
return;
/* Memory of jp2->cl will be freed by opj_jp2_destroy */
return OPJ_FALSE;
}
jp2->h = image->y1 - image->y0; /* HEIGHT */
@ -1650,6 +1664,8 @@ void opj_jp2_setup_encoder( opj_jp2_t *jp2,
jp2->approx = 0; /* APPROX */
jp2->jpip_on = parameters->jpip_on;
return OPJ_TRUE;
}
OPJ_BOOL opj_jp2_encode(opj_jp2_t *jp2,

View File

@ -278,8 +278,9 @@ OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2,
* @param parameters compression parameters
* @param image input filled image
* @param p_manager FIXME DOC
* @return OPJ_TRUE if successful, OPJ_FALSE otherwise
*/
void opj_jp2_setup_encoder( opj_jp2_t *jp2,
OPJ_BOOL opj_jp2_setup_encoder( opj_jp2_t *jp2,
opj_cparameters_t *parameters,
opj_image_t *image,
opj_event_mgr_t * p_manager);

View File

@ -362,7 +362,9 @@ static INLINE void opj_mqc_renormd(opj_mqc_t *const mqc) {
opj_mqc_t* opj_mqc_create(void) {
opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t));
#ifdef MQC_PERF_OPT
if (mqc) {
mqc->buffer = NULL;
}
#endif
return mqc;
}
@ -370,7 +372,9 @@ opj_mqc_t* opj_mqc_create(void) {
void opj_mqc_destroy(opj_mqc_t *mqc) {
if(mqc) {
#ifdef MQC_PERF_OPT
if (mqc->buffer) {
opj_free(mqc->buffer);
}
#endif
opj_free(mqc);
}

View File

@ -572,7 +572,7 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
l_codec->m_codec_data.m_compression.opj_destroy = (void (*) (void *)) opj_j2k_destroy;
l_codec->m_codec_data.m_compression.opj_setup_encoder = (void (*) ( void *,
l_codec->m_codec_data.m_compression.opj_setup_encoder = (OPJ_BOOL (*) ( void *,
opj_cparameters_t *,
struct opj_image *,
struct opj_event_mgr * )) opj_j2k_setup_encoder;
@ -609,7 +609,7 @@ opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format)
l_codec->m_codec_data.m_compression.opj_destroy = (void (*) (void *)) opj_jp2_destroy;
l_codec->m_codec_data.m_compression.opj_setup_encoder = (void (*) ( void *,
l_codec->m_codec_data.m_compression.opj_setup_encoder = (OPJ_BOOL (*) ( void *,
opj_cparameters_t *,
struct opj_image *,
struct opj_event_mgr * )) opj_jp2_setup_encoder;

View File

@ -142,7 +142,7 @@ typedef struct opj_codec_private
void (* opj_destroy) (void * p_codec);
void (* opj_setup_encoder) ( void * p_codec,
OPJ_BOOL (* opj_setup_encoder) ( void * p_codec,
opj_cparameters_t * p_param,
struct opj_image * p_image,
struct opj_event_mgr * p_manager);

View File

@ -1170,6 +1170,7 @@ OPJ_BOOL opj_t1_allocate_buffers(
opj_aligned_free(t1->data);
t1->data = (OPJ_INT32*) opj_aligned_malloc(datasize * sizeof(OPJ_INT32));
if(!t1->data){
/* FIXME event manager error callback */
return OPJ_FALSE;
}
t1->datasize=datasize;
@ -1183,6 +1184,7 @@ OPJ_BOOL opj_t1_allocate_buffers(
opj_aligned_free(t1->flags);
t1->flags = (opj_flag_t*) opj_aligned_malloc(flagssize * sizeof(opj_flag_t));
if(!t1->flags){
/* FIXME event manager error callback */
return OPJ_FALSE;
}
t1->flagssize=flagssize;

View File

@ -598,6 +598,10 @@ OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno,
}
bio = opj_bio_create();
if (!bio) {
/* FIXME event manager error callback */
return OPJ_FALSE;
}
opj_bio_init_enc(bio, c, length);
opj_bio_write(bio, 1, 1); /* Empty header bit */
@ -1128,7 +1132,8 @@ OPJ_BOOL opj_t2_read_packet_data( opj_t2_t* p_t2,
}
do {
if (l_current_data + l_seg->newlen > p_src_data + p_max_length) {
/* Check possible overflow (on l_current_data only, assumes input args already checked) then size */
if (((OPJ_SIZE_T)(l_current_data + l_seg->newlen) < (OPJ_SIZE_T)l_current_data) || (l_current_data + l_seg->newlen > p_src_data + p_max_length)) {
fprintf(stderr, "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n",
l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno);
return OPJ_FALSE;

View File

@ -465,6 +465,10 @@ OPJ_BOOL opj_tcd_rateallocate( opj_tcd_t *tcd,
tile_info->numpix = tcd_tile->numpix;
tile_info->distotile = tcd_tile->distotile;
tile_info->thresh = (OPJ_FLOAT64 *) opj_malloc(tcd_tcp->numlayers * sizeof(OPJ_FLOAT64));
if (!tile_info->thresh) {
/* FIXME event manager error callback */
return OPJ_FALSE;
}
}
for (layno = 0; layno < tcd_tcp->numlayers; layno++) {
@ -1121,6 +1125,10 @@ OPJ_BOOL opj_tcd_encode_tile( opj_tcd_t *p_tcd,
p_cstr_info->tile[p_tile_no].pdy[i] = (int)l_tccp->prch[i];
}
p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t*) opj_calloc((size_t)p_cstr_info->numcomps * (size_t)p_cstr_info->numlayers * l_num_packs, sizeof(opj_packet_info_t));
if (!p_cstr_info->tile[p_tile_no].packet) {
/* FIXME event manager error callback */
return OPJ_FALSE;
}
}
/* << INDEX */