From be83cfbe84b98c812258615e0d75fc7b88325e98 Mon Sep 17 00:00:00 2001 From: tbeu Date: Tue, 16 Oct 2018 16:30:00 +0200 Subject: [PATCH] Avoid integer multiplication overflows --- src/mat.c | 16 +++++---- src/mat4.c | 2 +- src/mat5.c | 81 ++++++++++++++++++++++++--------------------- src/matvar_struct.c | 19 ++++++----- src/read_data.c | 37 +++++++++++---------- tools/matdump.c | 2 +- 6 files changed, 84 insertions(+), 73 deletions(-) diff --git a/src/mat.c b/src/mat.c index 3446213e..6ef2b820 100644 --- a/src/mat.c +++ b/src/mat.c @@ -1688,7 +1688,7 @@ Mat_CalcSubscripts2(int rank,size_t *dims,size_t index) size_t Mat_VarGetSize(matvar_t *matvar) { - int i; + size_t i; size_t bytes = 0, overhead = 0, ptr = 0; #if defined(_WIN64) || (defined(__SIZEOF_POINTER__) && (__SIZEOF_POINTER__ == 8)) || (defined(SIZEOF_VOID_P) && (SIZEOF_VOID_P == 8)) @@ -1703,9 +1703,10 @@ Mat_VarGetSize(matvar_t *matvar) if ( matvar->class_type == MAT_C_STRUCT ) { int nfields = matvar->internal->num_fields; - int nmemb = 1; - for ( i = 0; i < matvar->rank; i++ ) - nmemb *= matvar->dims[i]; + size_t nmemb = 1; + int j; + for ( j = 0; j < matvar->rank; j++ ) + nmemb *= matvar->dims[j]; if ( nmemb*nfields > 0 ) { matvar_t **fields = (matvar_t**)matvar->data; if ( NULL != fields ) { @@ -1724,7 +1725,7 @@ Mat_VarGetSize(matvar_t *matvar) } else if ( matvar->class_type == MAT_C_CELL ) { matvar_t **cells = (matvar_t**)matvar->data; if ( NULL != cells ) { - int ncells = matvar->nbytes / matvar->data_size; + size_t ncells = matvar->nbytes / matvar->data_size; bytes = ncells*overhead; for ( i = 0; i < ncells; i++ ) { if ( NULL != cells[i] ) { @@ -1754,8 +1755,9 @@ Mat_VarGetSize(matvar_t *matvar) } else { if ( matvar->rank > 0 ) { size_t nmemb = 1; - for ( i = 0; i < matvar->rank; i++ ) - nmemb *= matvar->dims[i]; + int j; + for ( j = 0; j < matvar->rank; j++ ) + nmemb *= matvar->dims[j]; bytes = nmemb*Mat_SizeOfClass(matvar->class_type); if ( matvar->isComplex ) bytes *= 2; diff --git a/src/mat4.c b/src/mat4.c index c0f61872..f45599d7 100644 --- a/src/mat4.c +++ b/src/mat4.c @@ -282,7 +282,7 @@ Mat_VarWrite4(mat_t *mat,matvar_t *matvar) void Read4(mat_t *mat,matvar_t *matvar) { - unsigned int N; + size_t N; (void)fseek((FILE*)mat->fp,matvar->internal->datapos,SEEK_SET); diff --git a/src/mat5.c b/src/mat5.c index 61ce6b8c..a24c918a 100644 --- a/src/mat5.c +++ b/src/mat5.c @@ -29,13 +29,17 @@ */ /* FIXME: Implement Unicode support */ +#include #include #include #include #include #include #if defined(_MSC_VER) || defined(__MINGW32__) +# define SIZE_T_FMTSTR "Iu" # define strdup _strdup +#else +# define SIZE_T_FMTSTR "zu" #endif #include "matio_private.h" #include "mat5.h" @@ -857,16 +861,16 @@ WriteCompressedEmptyData(mat_t *mat,z_streamp z,int N, do { \ int i, j; \ long pos, row_stride, col_stride, pos2; \ - row_stride = (stride[0]-1)*data_size; \ - col_stride = stride[1]*dims[0]*data_size; \ - (void)fseek((FILE*)mat->fp,start[1]*dims[0]*data_size,SEEK_CUR); \ + row_stride = (long)(stride[0]-1)*data_size; \ + col_stride = (long)stride[1]*dims[0]*data_size; \ + (void)fseek((FILE*)mat->fp,(long)start[1]*dims[0]*data_size,SEEK_CUR); \ for ( i = 0; i < edge[1]; i++ ) { \ pos = ftell((FILE*)mat->fp); \ if ( pos == -1L ) { \ Mat_Critical("Couldn't determine file position"); \ return -1; \ } \ - (void)fseek((FILE*)mat->fp,start[0]*data_size,SEEK_CUR); \ + (void)fseek((FILE*)mat->fp,(long)start[0]*data_size,SEEK_CUR); \ for ( j = 0; j < edge[0]; j++ ) { \ fwrite(ptr++,data_size,1,(FILE*)mat->fp); \ (void)fseek((FILE*)mat->fp,row_stride,SEEK_CUR); \ @@ -901,7 +905,8 @@ int WriteDataSlab2(mat_t *mat,void *data,enum matio_types data_type,size_t *dims, int *start,int *stride,int *edge) { - int nBytes = 0, data_size; + int nBytes = 0; + size_t data_size; if ( (mat == NULL) || (data == NULL) || (mat->fp == NULL) || (start == NULL) || (stride == NULL) || (edge == NULL) ) { @@ -1187,13 +1192,12 @@ WriteCompressedData(mat_t *mat,z_streamp z,void *data,int N, static size_t ReadNextCell( mat_t *mat, matvar_t *matvar ) { - size_t bytesread = 0; - int ncells, i; + size_t bytesread = 0, ncells = 1, i; + int j; matvar_t **cells = NULL; - ncells = 1; - for ( i = 0; i < matvar->rank; i++ ) - ncells *= matvar->dims[i]; + for ( j = 0; j < matvar->rank; j++ ) + ncells *= matvar->dims[j]; matvar->data_size = sizeof(matvar_t *); matvar->nbytes = ncells*matvar->data_size; matvar->data = calloc(ncells, matvar->data_size); @@ -1214,7 +1218,7 @@ ReadNextCell( mat_t *mat, matvar_t *matvar ) for ( i = 0; i < ncells; i++ ) { cells[i] = Mat_VarCalloc(); if ( NULL == cells[i] ) { - Mat_Critical("Couldn't allocate memory for cell %d", i); + Mat_Critical("Couldn't allocate memory for cell %" SIZE_T_FMTSTR, i); continue; } @@ -1235,7 +1239,7 @@ ReadNextCell( mat_t *mat, matvar_t *matvar ) } else if ( uncomp_buf[0] != MAT_T_MATRIX ) { Mat_VarFree(cells[i]); cells[i] = NULL; - Mat_Critical("cells[%d], Uncompressed type not MAT_T_MATRIX",i); + Mat_Critical("cells[%" SIZE_T_FMTSTR "], Uncompressed type not MAT_T_MATRIX", i); break; } cells[i]->compression = MAT_COMPRESSION_ZLIB; @@ -1369,7 +1373,7 @@ ReadNextCell( mat_t *mat, matvar_t *matvar ) int cell_bytes_read,name_len; cells[i] = Mat_VarCalloc(); if ( !cells[i] ) { - Mat_Critical("Couldn't allocate memory for cell %d", i); + Mat_Critical("Couldn't allocate memory for cell %" SIZE_T_FMTSTR, i); continue; } @@ -1393,7 +1397,7 @@ ReadNextCell( mat_t *mat, matvar_t *matvar ) } else if ( buf[0] != MAT_T_MATRIX ) { Mat_VarFree(cells[i]); cells[i] = NULL; - Mat_Critical("cells[%d] not MAT_T_MATRIX, fpos = %ld",i, + Mat_Critical("cells[%" SIZE_T_FMTSTR "] not MAT_T_MATRIX, fpos = %ld", i, ftell((FILE*)mat->fp)); break; } @@ -1473,17 +1477,17 @@ ReadNextCell( mat_t *mat, matvar_t *matvar ) static size_t ReadNextStructField( mat_t *mat, matvar_t *matvar ) { - int fieldname_size,nfields, nmemb = 1, i; - size_t bytesread = 0; + int fieldname_size, j; + size_t bytesread = 0, nfields, nmemb = 1, i; matvar_t **fields = NULL; - for ( i = 0; i < matvar->rank; i++ ) - nmemb *= matvar->dims[i]; + for ( j = 0; j < matvar->rank; j++ ) + nmemb *= matvar->dims[j]; if ( matvar->compression == MAT_COMPRESSION_ZLIB ) { #if defined(HAVE_ZLIB) mat_uint32_t uncomp_buf[16] = {0,}; - int nbytes, j; + int nbytes; mat_uint32_t array_flags; int err; @@ -1548,9 +1552,10 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar ) fields = (matvar_t**)matvar->data; for ( i = 0; i < nmemb; i++ ) { - for ( j = 0; j < nfields; j++ ) { - fields[i*nfields+j] = Mat_VarCalloc(); - fields[i*nfields+j]->name = strdup(matvar->internal->fieldnames[j]); + size_t k; + for ( k = 0; k < nfields; k++ ) { + fields[i*nfields+k] = Mat_VarCalloc(); + fields[i*nfields+k]->name = strdup(matvar->internal->fieldnames[k]); } } @@ -1565,7 +1570,7 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar ) if ( uncomp_buf[0] != MAT_T_MATRIX ) { Mat_VarFree(fields[i]); fields[i] = NULL; - Mat_Critical("fields[%d], Uncompressed type not MAT_T_MATRIX",i); + Mat_Critical("fields[%" SIZE_T_FMTSTR "], Uncompressed type not MAT_T_MATRIX", i); continue; } else if ( 0 == nbytes ) { /* Empty field: Memory optimization */ @@ -1607,8 +1612,7 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar ) } /* Rank and dimension */ if ( uncomp_buf[0] == MAT_T_INT32 ) { - int j = 0; - + j = 0; fields[i]->rank = uncomp_buf[1]; nbytes -= fields[i]->rank; fields[i]->rank /= 4; @@ -1670,7 +1674,7 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar ) #endif } else { mat_uint32_t buf[6]; - int nBytes,j; + int nBytes; mat_uint32_t array_flags; bytesread+=fread(buf,4,2,(FILE*)mat->fp); @@ -1728,9 +1732,10 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar ) fields = (matvar_t**)matvar->data; for ( i = 0; i < nmemb; i++ ) { - for ( j = 0; j < nfields; j++ ) { - fields[i*nfields+j] = Mat_VarCalloc(); - fields[i*nfields+j]->name = strdup(matvar->internal->fieldnames[j]); + size_t k; + for ( k = 0; k < nfields; k++ ) { + fields[i*nfields+k] = Mat_VarCalloc(); + fields[i*nfields+k]->name = strdup(matvar->internal->fieldnames[k]); } } @@ -1745,7 +1750,7 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar ) if ( buf[0] != MAT_T_MATRIX ) { Mat_VarFree(fields[i]); fields[i] = NULL; - Mat_Critical("fields[%d] not MAT_T_MATRIX, fpos = %ld",i, + Mat_Critical("fields[%" SIZE_T_FMTSTR "] not MAT_T_MATRIX, fpos = %ld", i, ftell((FILE*)mat->fp)); return bytesread; } else if ( 0 == nBytes ) { @@ -1813,11 +1818,11 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar ) static size_t ReadNextFunctionHandle(mat_t *mat, matvar_t *matvar) { - int nfunctions = 1, i; - size_t bytesread = 0; + int j; + size_t bytesread = 0, nfunctions = 1, i; - for ( i = 0; i < matvar->rank; i++ ) - nfunctions *= matvar->dims[i]; + for ( j = 0; j < matvar->rank; j++ ) + nfunctions *= matvar->dims[j]; matvar->data = malloc(nfunctions*sizeof(matvar_t *)); if ( matvar->data != NULL ) { @@ -4080,8 +4085,8 @@ Read5(mat_t *mat, matvar_t *matvar) ptr_in += stride[0]; \ I += stride[0]; \ } \ - I += dims[0]-edge[0]*stride[0]-start[0]; \ - ptr_in += dims[0]-edge[0]*stride[0]-start[0]; \ + I += dims[0]-(ptrdiff_t)edge[0]*stride[0]-start[0]; \ + ptr_in += dims[0]-(ptrdiff_t)edge[0]*stride[0]-start[0]; \ GET_DATA_SLABN_RANK_LOOP; \ } \ } \ @@ -4449,7 +4454,7 @@ GetDataSlab(void *data_in, void *data_out, enum matio_classes class_type, do { \ ptr_in += start; \ if ( !stride ) { \ - memcpy(ptr, ptr_in, edge*data_size); \ + memcpy(ptr, ptr_in, (size_t)edge*data_size); \ } else { \ int i; \ for ( i = 0; i < edge; i++ ) \ @@ -4462,7 +4467,7 @@ GetDataLinear(void *data_in, void *data_out, enum matio_classes class_type, enum matio_types data_type, int start, int stride, int edge) { int err = 0; - int data_size = Mat_SizeOf(data_type); + size_t data_size = Mat_SizeOf(data_type); switch ( class_type ) { case MAT_C_DOUBLE: diff --git a/src/matvar_struct.c b/src/matvar_struct.c index 7b7cbf78..b74ee874 100644 --- a/src/matvar_struct.c +++ b/src/matvar_struct.c @@ -45,7 +45,8 @@ matvar_t * Mat_VarCreateStruct(const char *name,int rank,size_t *dims,const char **fields, unsigned nfields) { - int i, nmemb = 1; + size_t i, nmemb = 1; + int j; matvar_t *matvar; if ( NULL == dims ) @@ -60,9 +61,9 @@ Mat_VarCreateStruct(const char *name,int rank,size_t *dims,const char **fields, matvar->name = strdup(name); matvar->rank = rank; matvar->dims = (size_t*)malloc(matvar->rank*sizeof(*matvar->dims)); - for ( i = 0; i < matvar->rank; i++ ) { - matvar->dims[i] = dims[i]; - nmemb *= dims[i]; + for ( j = 0; j < matvar->rank; j++ ) { + matvar->dims[j] = dims[j]; + nmemb *= dims[j]; } matvar->class_type = MAT_C_STRUCT; matvar->data_type = MAT_T_STRUCT; @@ -113,15 +114,16 @@ Mat_VarCreateStruct(const char *name,int rank,size_t *dims,const char **fields, int Mat_VarAddStructField(matvar_t *matvar,const char *fieldname) { - int i, f, nfields, nmemb, cnt = 0; + int j, cnt = 0; + size_t i, nfields, nmemb; matvar_t **new_data, **old_data; char **fieldnames; if ( matvar == NULL || fieldname == NULL ) return -1; nmemb = 1; - for ( i = 0; i < matvar->rank; i++ ) - nmemb *= matvar->dims[i]; + for ( j = 0; j < matvar->rank; j++ ) + nmemb *= matvar->dims[j]; nfields = matvar->internal->num_fields+1; matvar->internal->num_fields = nfields; @@ -138,6 +140,7 @@ Mat_VarAddStructField(matvar_t *matvar,const char *fieldname) old_data = (matvar_t**)matvar->data; for ( i = 0; i < nmemb; i++ ) { + size_t f; for ( f = 0; f < nfields-1; f++ ) new_data[cnt++] = old_data[i*(nfields-1)+f]; new_data[cnt++] = NULL; @@ -445,7 +448,7 @@ Mat_VarGetStructsLinear(matvar_t *matvar,int start,int stride,int edge, nfields = matvar->internal->num_fields; - struct_slab->nbytes = edge*nfields*sizeof(matvar_t *); + struct_slab->nbytes = (size_t)edge*nfields*sizeof(matvar_t *); struct_slab->data = malloc(struct_slab->nbytes); struct_slab->dims[0] = edge; struct_slab->dims[1] = 1; diff --git a/src/read_data.c b/src/read_data.c index c736c22c..14895643 100644 --- a/src/read_data.c +++ b/src/read_data.c @@ -29,6 +29,7 @@ */ /* FIXME: Implement Unicode support */ +#include #include #include #include @@ -1437,10 +1438,10 @@ ReadCharData(mat_t *mat,char *data,enum matio_types data_type,int len) cnt[j] = 0; \ if ( (I % dimp[j]) != 0 ) { \ (void)fseek((FILE*)mat->fp,data_size*(dimp[j]-(I % dimp[j]) + dimp[j-1]*start[j]),SEEK_CUR); \ - I += dimp[j]-(I % dimp[j]) + dimp[j-1]*start[j]; \ + I += dimp[j]-(I % dimp[j]) + (ptrdiff_t)dimp[j-1]*start[j]; \ } else if ( start[j] ) { \ (void)fseek((FILE*)mat->fp,data_size*(dimp[j-1]*start[j]),SEEK_CUR); \ - I += dimp[j-1]*start[j]; \ + I += (ptrdiff_t)dimp[j-1]*start[j]; \ } \ } else { \ I += inc[j]; \ @@ -1464,7 +1465,7 @@ ReadCharData(mat_t *mat,char *data,enum matio_types data_type,int len) dimp[i] *= dims[j+1]; \ } \ N *= edge[i]; \ - I += dimp[i-1]*start[i]; \ + I += (ptrdiff_t)dimp[i-1]*start[i]; \ } \ (void)fseek((FILE*)mat->fp,I*data_size,SEEK_CUR); \ if ( stride[0] == 1 ) { \ @@ -1490,9 +1491,9 @@ ReadCharData(mat_t *mat,char *data,enum matio_types data_type,int len) (void)fseek((FILE*)mat->fp,data_size*(stride[0]-1),SEEK_CUR); \ I += stride[0]; \ } \ - I += dims[0]-edge[0]*stride[0]-start[0]; \ + I += dims[0]-(ptrdiff_t)edge[0]*stride[0]-start[0]; \ (void)fseek((FILE*)mat->fp,data_size* \ - (dims[0]-edge[0]*stride[0]-start[0]),SEEK_CUR); \ + (dims[0]-(ptrdiff_t)edge[0]*stride[0]-start[0]),SEEK_CUR); \ READ_DATA_SLABN_RANK_LOOP; \ } \ } \ @@ -1613,10 +1614,10 @@ ReadDataSlabN(mat_t *mat,void *data,enum matio_classes class_type, cnt[j] = 0; \ if ( (I % dimp[j]) != 0 ) { \ InflateSkipData(mat,&z_copy,data_type, dimp[j]-(I % dimp[j]) + dimp[j-1]*start[j]); \ - I += dimp[j]-(I % dimp[j]) + dimp[j-1]*start[j]; \ + I += dimp[j]-(I % dimp[j]) + (ptrdiff_t)dimp[j-1]*start[j]; \ } else if ( start[j] ) { \ InflateSkipData(mat,&z_copy,data_type, dimp[j-1]*start[j]); \ - I += dimp[j-1]*start[j]; \ + I += (ptrdiff_t)dimp[j-1]*start[j]; \ } \ } else { \ if ( inc[j] ) { \ @@ -1642,7 +1643,7 @@ ReadDataSlabN(mat_t *mat,void *data,enum matio_classes class_type, dimp[i] *= dims[j+1]; \ } \ N *= edge[i]; \ - I += dimp[i-1]*start[i]; \ + I += (ptrdiff_t)dimp[i-1]*start[i]; \ } \ /* Skip all data to the starting indices */ \ InflateSkipData(mat,&z_copy,data_type,I); \ @@ -1669,8 +1670,8 @@ ReadDataSlabN(mat_t *mat,void *data,enum matio_classes class_type, I += stride[0]; \ } \ ReadDataFunc(mat,&z_copy,ptr+i+j,data_type,1); \ - I += dims[0]-(edge[0]-1)*stride[0]-start[0]; \ - InflateSkipData(mat,&z_copy,data_type,dims[0]-(edge[0]-1)*stride[0]-start[0]-1); \ + I += dims[0]-(ptrdiff_t)(edge[0]-1)*stride[0]-start[0]; \ + InflateSkipData(mat,&z_copy,data_type,dims[0]-(ptrdiff_t)(edge[0]-1)*stride[0]-start[0]-1); \ READ_COMPRESSED_DATA_SLABN_RANK_LOOP; \ } \ } \ @@ -1901,23 +1902,23 @@ ReadDataSlab1(mat_t *mat,void *data,enum matio_classes class_type, /* data so get rid of the loops. */ \ if ( (stride[0] == 1 && edge[0] == dims[0]) && \ (stride[1] == 1) ) { \ - ReadDataFunc(mat,ptr,data_type,edge[0]*edge[1]); \ + ReadDataFunc(mat,ptr,data_type,(ptrdiff_t)edge[0]*edge[1]); \ } else { \ - row_stride = (stride[0]-1)*data_size; \ - col_stride = stride[1]*dims[0]*data_size; \ + row_stride = (long)(stride[0]-1)*data_size; \ + col_stride = (long)stride[1]*dims[0]*data_size; \ pos = ftell((FILE*)mat->fp); \ if ( pos == -1L ) { \ Mat_Critical("Couldn't determine file position"); \ return -1; \ } \ - (void)fseek((FILE*)mat->fp,start[1]*dims[0]*data_size,SEEK_CUR); \ + (void)fseek((FILE*)mat->fp,(long)start[1]*dims[0]*data_size,SEEK_CUR); \ for ( i = 0; i < edge[1]; i++ ) { \ pos = ftell((FILE*)mat->fp); \ if ( pos == -1L ) { \ Mat_Critical("Couldn't determine file position"); \ return -1; \ } \ - (void)fseek((FILE*)mat->fp,start[0]*data_size,SEEK_CUR); \ + (void)fseek((FILE*)mat->fp,(long)start[0]*data_size,SEEK_CUR); \ for ( j = 0; j < edge[0]; j++ ) { \ ReadDataFunc(mat,ptr++,data_type,1); \ (void)fseek((FILE*)mat->fp,row_stride,SEEK_CUR); \ @@ -2161,13 +2162,13 @@ ReadCompressedDataSlab1(mat_t *mat,z_streamp z,void *data, /* to speed up the code */ \ if ( (stride[0] == 1 && edge[0] == dims[0]) && \ (stride[1] == 1) ) { \ - ReadDataFunc(mat,&z_copy,ptr,data_type,edge[0]*edge[1]); \ + ReadDataFunc(mat,&z_copy,ptr,data_type,(ptrdiff_t)edge[0]*edge[1]); \ } else if ( stride[0] == 1 ) { \ for ( i = 0; i < edge[1]; i++ ) { \ InflateSkipData(mat,&z_copy,data_type,start[0]); \ ReadDataFunc(mat,&z_copy,ptr,data_type,edge[0]); \ ptr += edge[0]; \ - pos = dims[0]-(edge[0]-1)*stride[0]-1-start[0] + col_stride; \ + pos = dims[0]-(ptrdiff_t)(edge[0]-1)*stride[0]-1-start[0] + col_stride; \ InflateSkipData(mat,&z_copy,data_type,pos); \ } \ } else { \ @@ -2178,7 +2179,7 @@ ReadCompressedDataSlab1(mat_t *mat,z_streamp z,void *data, InflateSkipData(mat,&z_copy,data_type,row_stride); \ } \ ReadDataFunc(mat,&z_copy,ptr++,data_type,1); \ - pos = dims[0]-(edge[0]-1)*stride[0]-1-start[0] + col_stride; \ + pos = dims[0]-(ptrdiff_t)(edge[0]-1)*stride[0]-1-start[0] + col_stride; \ InflateSkipData(mat,&z_copy,data_type,pos); \ } \ } \ diff --git a/tools/matdump.c b/tools/matdump.c index d412fa8c..f8588d47 100644 --- a/tools/matdump.c +++ b/tools/matdump.c @@ -359,7 +359,7 @@ read_selected_data(mat_t *mat,matvar_t **_matvar,char *index_str) /* Check if the users selection is valid and if so read the data */ if ((nmemb = slab_select_valid(rank,start,stride,edge,matvar))) { matvar->data_size = Mat_SizeOfClass(matvar->class_type); - matvar->nbytes = nmemb*matvar->data_size; + matvar->nbytes = (size_t)nmemb*matvar->data_size; if ( matvar->isComplex ) { mat_complex_split_t *z; matvar->data = malloc(sizeof(*z));