Description: Fix reading variables from MAT v5 file
 Fixes:
 CVE-2019-9026
 CVE-2019-9027
 CVE-2019-9028
 CVE-2019-9029
 CVE-2019-9030
 CVE-2019-9031
 CVE-2019-9032
 CVE-2019-9033
 CVE-2019-9034
 CVE-2019-9035
 CVE-2019-9038
Origin: backport, https://github.com/tbeu/matio/commit/a0539135c9b1ab7613aa7953279da9224da88775
                  https://github.com/tbeu/matio/commit/adfa218770183cf93f74e7fad5055921ae1f9958
                  https://github.com/tbeu/matio/commit/02625a0e394eeb8bf3ea61641f73de907296a2c4
Bug: https://github.com/tbeu/matio/issues/103
Bug-Debian: https://bugs.debian.org/924185
Last-Update: 2019-03-23
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/src/inflate.c
+++ b/src/inflate.c
@@ -339,15 +339,17 @@ InflateArrayFlags(mat_t *mat, matvar_t *
  * @param mat Pointer to the MAT file
  * @param matvar Pointer to the MAT variable
  * @param buf Pointer to store the dimensions flag and data
+ * @param nbytes Size of buf in bytes
+ * @param dims Output buffer to be allocated if (8+4*rank) > nbytes
  * @return Number of bytes read from the file
  */
 size_t
-InflateDimensions(mat_t *mat, matvar_t *matvar, void *buf)
+InflateRankDims(mat_t *mat, matvar_t *matvar, void *buf, size_t nbytes, mat_uint32_t** dims)
 {
     mat_uint8_t comp_buf[32];
     mat_int32_t tag[2];
     int    err, rank, i;
-    size_t bytesread = 0;
+    size_t bytesread = 0, readresult = 1;
 
     if ( buf == NULL )
         return 0;
@@ -361,16 +363,17 @@ InflateDimensions(mat_t *mat, matvar_t *
     matvar->internal->z->next_out = (Bytef*)buf;
     err = inflate(matvar->internal->z,Z_NO_FLUSH);
     if ( err != Z_OK ) {
-        Mat_Critical("InflateDimensions: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
+        Mat_Critical("InflateRankDims: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
         return bytesread;
     }
-    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in ) {
+    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in && 1 == readresult ) {
         matvar->internal->z->avail_in = 1;
         matvar->internal->z->next_in = comp_buf;
-        bytesread += fread(comp_buf,1,1,(FILE*)mat->fp);
+        readresult = fread(comp_buf,1,1,(FILE*)mat->fp);
+        bytesread += readresult;
         err = inflate(matvar->internal->z,Z_NO_FLUSH);
         if ( err != Z_OK ) {
-            Mat_Critical("InflateDimensions: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
+            Mat_Critical("InflateRankDims: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
             return bytesread;
         }
     }
@@ -381,7 +384,7 @@ InflateDimensions(mat_t *mat, matvar_t *
         Mat_int32Swap(tag+1);
     }
     if ( (tag[0] & 0x0000ffff) != MAT_T_INT32 ) {
-        Mat_Critical("InflateDimensions: Reading dimensions expected type MAT_T_INT32");
+        Mat_Critical("InflateRankDims: Reading dimensions expected type MAT_T_INT32");
         return bytesread;
     }
     rank = tag[1];
@@ -396,11 +399,24 @@ InflateDimensions(mat_t *mat, matvar_t *
         matvar->internal->z->next_in = comp_buf;
         bytesread += fread(comp_buf,1,1,(FILE*)mat->fp);
     }
+
     matvar->internal->z->avail_out = rank;
-    matvar->internal->z->next_out = (Bytef*)((mat_int32_t *)buf+2);
+    if ( sizeof(mat_uint32_t)*(rank + 2) <= nbytes ) {
+        matvar->internal->z->next_out = (Bytef*)((mat_int32_t *)buf+2);
+    } else {
+        /* Cannot use too small buf, but can allocate output buffer dims */
+        *dims = (mat_uint32_t*)calloc(rank, sizeof(mat_uint32_t));
+        if ( NULL != *dims ) {
+            matvar->internal->z->next_out = (Bytef*)*dims;
+        } else {
+            *((mat_int32_t *)buf+1) = 0;
+            Mat_Critical("Error allocating memory for dims");
+            return bytesread;
+        }
+    }
     err = inflate(matvar->internal->z,Z_NO_FLUSH);
     if ( err != Z_OK ) {
-        Mat_Critical("InflateDimensions: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
+        Mat_Critical("InflateRankDims: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
         return bytesread;
     }
     while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in ) {
@@ -436,7 +452,7 @@ InflateVarNameTag(mat_t *mat, matvar_t *
 {
     mat_uint8_t comp_buf[32];
     int    err;
-    size_t bytesread = 0;
+    size_t bytesread = 0, readresult = 1;
 
     if ( buf == NULL )
         return 0;
@@ -453,10 +469,11 @@ InflateVarNameTag(mat_t *mat, matvar_t *
         Mat_Critical("InflateVarNameTag: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
         return bytesread;
     }
-    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in ) {
+    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in && 1 == readresult ) {
         matvar->internal->z->avail_in = 1;
         matvar->internal->z->next_in = comp_buf;
-        bytesread += fread(comp_buf,1,1,(FILE*)mat->fp);
+        readresult = fread(comp_buf,1,1,(FILE*)mat->fp);
+        bytesread += readresult;
         err = inflate(matvar->internal->z,Z_NO_FLUSH);
         if ( err != Z_OK ) {
             Mat_Critical("InflateVarNameTag: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
@@ -487,7 +504,7 @@ InflateVarName(mat_t *mat, matvar_t *mat
 {
     mat_uint8_t comp_buf[32];
     int    err;
-    size_t bytesread = 0;
+    size_t bytesread = 0, readresult = 1;
 
     if ( buf == NULL )
         return 0;
@@ -504,10 +521,11 @@ InflateVarName(mat_t *mat, matvar_t *mat
         Mat_Critical("InflateVarName: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
         return bytesread;
     }
-    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in ) {
+    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in && 1 == readresult ) {
         matvar->internal->z->avail_in = 1;
         matvar->internal->z->next_in = comp_buf;
-        bytesread += fread(comp_buf,1,1,(FILE*)mat->fp);
+        readresult = fread(comp_buf,1,1,(FILE*)mat->fp);
+        bytesread += readresult;
         err = inflate(matvar->internal->z,Z_NO_FLUSH);
         if ( err != Z_OK ) {
             Mat_Critical("InflateVarName: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
@@ -593,7 +611,7 @@ InflateDataType(mat_t *mat, z_streamp z,
 {
     mat_uint8_t comp_buf[32];
     int    err;
-    size_t bytesread = 0;
+    size_t bytesread = 0, readresult = 1;
 
     if ( buf == NULL )
         return 0;
@@ -610,10 +628,11 @@ InflateDataType(mat_t *mat, z_streamp z,
         Mat_Critical("InflateDataType: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
         return bytesread;
     }
-    while ( z->avail_out && !z->avail_in ) {
+    while ( z->avail_out && !z->avail_in && 1 == readresult ) {
         z->avail_in = 1;
         z->next_in = comp_buf;
-        bytesread += fread(comp_buf,1,1,(FILE*)mat->fp);
+        readresult = fread(comp_buf,1,1,(FILE*)mat->fp);
+        bytesread += readresult;
         err = inflate(z,Z_NO_FLUSH);
         if ( err != Z_OK ) {
             Mat_Critical("InflateDataType: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
@@ -714,7 +733,7 @@ InflateFieldNameLength(mat_t *mat, matva
 {
     mat_uint8_t comp_buf[32];
     int    err;
-    size_t bytesread = 0;
+    size_t bytesread = 0, readresult = 1;
 
     if ( buf == NULL )
         return 0;
@@ -731,10 +750,11 @@ InflateFieldNameLength(mat_t *mat, matva
         Mat_Critical("InflateFieldNameLength: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
         return bytesread;
     }
-    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in ) {
+    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in && 1 == readresult ) {
         matvar->internal->z->avail_in = 1;
         matvar->internal->z->next_in = comp_buf;
-        bytesread += fread(comp_buf,1,1,(FILE*)mat->fp);
+        readresult = fread(comp_buf,1,1,(FILE*)mat->fp);
+        bytesread += readresult;
         err = inflate(matvar->internal->z,Z_NO_FLUSH);
         if ( err != Z_OK ) {
             Mat_Critical("InflateFieldNameLength: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
@@ -765,7 +785,7 @@ InflateFieldNamesTag(mat_t *mat, matvar_
 {
     mat_uint8_t comp_buf[32];
     int    err;
-    size_t bytesread = 0;
+    size_t bytesread = 0, readresult = 1;
 
     if ( buf == NULL )
         return 0;
@@ -782,10 +802,11 @@ InflateFieldNamesTag(mat_t *mat, matvar_
         Mat_Critical("InflateFieldNamesTag: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
         return bytesread;
     }
-    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in ) {
+    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in && 1 == readresult ) {
         matvar->internal->z->avail_in = 1;
         matvar->internal->z->next_in = comp_buf;
-        bytesread += fread(comp_buf,1,1,(FILE*)mat->fp);
+        readresult = fread(comp_buf,1,1,(FILE*)mat->fp);
+        bytesread += readresult;
         err = inflate(matvar->internal->z,Z_NO_FLUSH);
         if ( err != Z_OK ) {
             Mat_Critical("InflateFieldNamesTag: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
@@ -824,7 +845,7 @@ InflateFieldNames(mat_t *mat,matvar_t *m
 {
     mat_uint8_t comp_buf[32];
     int    err;
-    size_t bytesread = 0;
+    size_t bytesread = 0, readresult = 1;
 
     if ( buf == NULL )
         return 0;
@@ -841,10 +862,11 @@ InflateFieldNames(mat_t *mat,matvar_t *m
         Mat_Critical("InflateFieldNames: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
         return bytesread;
     }
-    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in ) {
+    while ( matvar->internal->z->avail_out && !matvar->internal->z->avail_in && 1 == readresult ) {
         matvar->internal->z->avail_in = 1;
         matvar->internal->z->next_in = comp_buf;
-        bytesread += fread(comp_buf,1,1,(FILE*)mat->fp);
+        readresult = fread(comp_buf,1,1,(FILE*)mat->fp);
+        bytesread += readresult;
         err = inflate(matvar->internal->z,Z_NO_FLUSH);
         if ( err != Z_OK ) {
             Mat_Critical("InflateFieldNames: inflate returned %s",zError(err == Z_NEED_DICT ? Z_DATA_ERROR : err));
--- a/src/mat5.c
+++ b/src/mat5.c
@@ -1849,7 +1849,13 @@ ReadNextCell( mat_t *mat, matvar_t *matv
                 bytesread+=InflateSkip(mat,matvar->internal->z,nbytes);
             }
             if ( cells[i]->class_type != MAT_C_OPAQUE ) {
-                bytesread += InflateDimensions(mat,matvar,uncomp_buf);
+                mat_uint32_t* dims = NULL;
+                int do_clean = 0;
+                bytesread += InflateRankDims(mat,matvar,uncomp_buf,sizeof(uncomp_buf),&dims);
+                if ( NULL == dims )
+                    dims = uncomp_buf + 2;
+                else
+                    do_clean = 1;
                 nbytes -= 8;
                 if ( mat->byteswap ) {
                     (void)Mat_uint32Swap(uncomp_buf);
@@ -1865,14 +1871,16 @@ ReadNextCell( mat_t *mat, matvar_t *matv
                     cells[i]->dims = (size_t*)malloc(cells[i]->rank*sizeof(*cells[i]->dims));
                     if ( mat->byteswap ) {
                         for ( j = 0; j < cells[i]->rank; j++ )
-                            cells[i]->dims[j] = Mat_uint32Swap(uncomp_buf+2+j);
+                            cells[i]->dims[j] = Mat_uint32Swap(dims + j);
                     } else {
                         for ( j = 0; j < cells[i]->rank; j++ )
-                            cells[i]->dims[j] = uncomp_buf[2+j];
+                            cells[i]->dims[j] = dims[j];
                     }
                     if ( cells[i]->rank % 2 != 0 )
                         nbytes -= 4;
                 }
+                if ( do_clean )
+                    free(dims);
                 bytesread += InflateVarNameTag(mat,matvar,uncomp_buf);
                 nbytes -= 8;
                 if ( mat->byteswap ) {
@@ -1882,24 +1890,28 @@ ReadNextCell( mat_t *mat, matvar_t *matv
                 /* Handle cell elements written with a variable name */
                 if ( uncomp_buf[1] > 0 ) {
                     /* Name of variable */
-                    int len = 0;
                     if ( uncomp_buf[0] == MAT_T_INT8 ) {    /* Name not in tag */
-                        len = uncomp_buf[1];
+                        mat_uint32_t len = uncomp_buf[1];
 
                         if ( len % 8 > 0 )
                             len = len+(8-(len % 8));
                         cells[i]->name = (char*)malloc(len+1);
-                        /* Inflate variable name */
-                        bytesread += InflateVarName(mat,matvar,cells[i]->name,len);
-                        cells[i]->name[len] = '\0';
                         nbytes -= len;
-                    } else if ( ((uncomp_buf[0] & 0x0000ffff) == MAT_T_INT8) &&
-                               ((uncomp_buf[0] & 0xffff0000) != 0x00) ) {
-                        /* Name packed in tag */
-                        len = (uncomp_buf[0] & 0xffff0000) >> 16;
-                        cells[i]->name = (char*)malloc(len+1);
-                        memcpy(cells[i]->name,uncomp_buf+1,len);
-                        cells[i]->name[len] = '\0';
+                        if ( NULL != cells[i]->name ) {
+                            /* Inflate variable name */
+                            bytesread += InflateVarName(mat,matvar,cells[i]->name,len);
+                            cells[i]->name[len] = '\0';
+                        }
+                    } else {
+                        mat_uint32_t len = (uncomp_buf[0] & 0xffff0000) >> 16;
+                        if ( ((uncomp_buf[0] & 0x0000ffff) == MAT_T_INT8) && len > 0 && len <= 4 ) {
+                            /* Name packed in tag */
+                            cells[i]->name = (char*)malloc(len+1);
+                            if ( NULL != cells[i]->name ) {
+                                memcpy(cells[i]->name,uncomp_buf+1,len);
+                                cells[i]->name[len] = '\0';
+                            }
+                        }
                     }
                 }
                 cells[i]->internal->z = (z_streamp)calloc(1,sizeof(z_stream));
@@ -2085,8 +2097,9 @@ ReadNextCell( mat_t *mat, matvar_t *matv
 static size_t
 ReadNextStructField( mat_t *mat, matvar_t *matvar )
 {
-    int fieldname_size,nfields, nmemb = 1, i;
-    size_t bytesread = 0;
+    mat_uint32_t fieldname_size;
+    int j;
+    size_t bytesread = 0, nfields, nmemb = 1, i;
     matvar_t **fields = NULL;
 
     for ( i = 0; i < matvar->rank; i++ )
@@ -2127,18 +2140,22 @@ ReadNextStructField( mat_t *mat, matvar_
             i = 0;
         if ( nfields ) {
             char *ptr = (char*)malloc(nfields*fieldname_size+i);
-            bytesread += InflateFieldNames(mat,matvar,ptr,nfields,fieldname_size,i);
-            matvar->internal->num_fields = nfields;
-            matvar->internal->fieldnames =
-                (char**)calloc(nfields,sizeof(*matvar->internal->fieldnames));
-            for ( i = 0; i < nfields; i++ ) {
-                matvar->internal->fieldnames[i] = (char*)malloc(fieldname_size);
-                memcpy(matvar->internal->fieldnames[i],ptr+i*fieldname_size,
-                       fieldname_size);
-                matvar->internal->fieldnames[i][fieldname_size-1] = '\0';
-            }
+            if ( NULL != ptr ) {
+                bytesread += InflateFieldNames(mat,matvar,ptr,nfields,fieldname_size,i);
+                matvar->internal->num_fields = nfields;
+                matvar->internal->fieldnames =
+                    (char**)calloc(nfields,sizeof(*matvar->internal->fieldnames));
+                if ( NULL != matvar->internal->fieldnames ) {
+                    for ( i = 0; i < nfields; i++ ) {
+                        matvar->internal->fieldnames[i] = (char*)malloc(fieldname_size);
+                        if ( NULL != matvar->internal->fieldnames[i] ) {
+                            memcpy(matvar->internal->fieldnames[i], ptr+i*fieldname_size, fieldname_size);
+                            matvar->internal->fieldnames[i][fieldname_size-1] = '\0';
+                        }
+                    }
+                 }
             free(ptr);
-        } else {
+        } }else {
             matvar->internal->num_fields = 0;
             matvar->internal->fieldnames = NULL;
         }
@@ -2209,7 +2226,13 @@ ReadNextStructField( mat_t *mat, matvar_
                 bytesread+=InflateSkip(mat,matvar->internal->z,nbytes);
             }
             if ( fields[i]->class_type != MAT_C_OPAQUE ) {
-                bytesread += InflateDimensions(mat,matvar,uncomp_buf);
+                mat_uint32_t* dims = NULL;
+                int do_clean = 0;
+                bytesread += InflateRankDims(mat,matvar,uncomp_buf,sizeof(uncomp_buf),&dims);
+                if ( NULL == dims )
+                    dims = uncomp_buf + 2;
+                else
+                    do_clean = 1;
                 nbytes -= 8;
                 if ( mat->byteswap ) {
                     (void)Mat_uint32Swap(uncomp_buf);
@@ -2226,14 +2249,16 @@ ReadNextStructField( mat_t *mat, matvar_
                                              sizeof(*fields[i]->dims));
                     if ( mat->byteswap ) {
                         for ( j = 0; j < fields[i]->rank; j++ )
-                            fields[i]->dims[j] = Mat_uint32Swap(uncomp_buf+2+j);
+                            fields[i]->dims[j] = Mat_uint32Swap(dims+j);
                     } else {
                         for ( j = 0; j < fields[i]->rank; j++ )
-                            fields[i]->dims[j] = uncomp_buf[2+j];
+                            fields[i]->dims[j] = dims[j];
                     }
                     if ( fields[i]->rank % 2 != 0 )
                         nbytes -= 4;
                 }
+                if ( do_clean )
+                    free(dims);
                 bytesread += InflateVarNameTag(mat,matvar,uncomp_buf);
                 nbytes -= 8;
                 fields[i]->internal->z = (z_streamp)calloc(1,sizeof(z_stream));
@@ -2308,11 +2333,15 @@ ReadNextStructField( mat_t *mat, matvar_
             matvar->internal->num_fields = nfields;
             matvar->internal->fieldnames =
                 (char**)calloc(nfields,sizeof(*matvar->internal->fieldnames));
-            for ( i = 0; i < nfields; i++ ) {
-                matvar->internal->fieldnames[i] = (char*)malloc(fieldname_size);
-                bytesread+=fread(matvar->internal->fieldnames[i],1,fieldname_size,(FILE*)mat->fp);
-                matvar->internal->fieldnames[i][fieldname_size-1] = '\0';
+            if ( NULL != matvar->internal->fieldnames ) {
+                for ( i = 0; i < nfields; i++ ) {
+                    matvar->internal->fieldnames[i] = (char*)malloc(fieldname_size);
+                    if ( NULL != matvar->internal->fieldnames[i] ) {
+                        bytesread+=fread(matvar->internal->fieldnames[i],1,fieldname_size,(FILE*)mat->fp);
+                        matvar->internal->fieldnames[i][fieldname_size-1] = '\0';
+                    }
             }
+         }
         } else {
             matvar->internal->num_fields = 0;
             matvar->internal->fieldnames = NULL;
@@ -4297,11 +4326,21 @@ Read5(mat_t *mat, matvar_t *matvar)
             }
             matvar->data_size = sizeof(char);
             matvar->nbytes = len*matvar->data_size;
+            if ( matvar->isComplex ) {
+                break;
+            }
             matvar->data   = calloc(matvar->nbytes+1,1);
             if ( NULL == matvar->data ) {
                 Mat_Critical("Failed to allocate %d bytes",matvar->nbytes);
                 break;
             }
+            {
+                size_t nbytes;
+                err = SafeMul(&nbytes, len, matvar->data_size);
+                if ( err || nbytes > matvar->nbytes ) {
+                    break;
+                }
+            }
             if ( matvar->compression == MAT_COMPRESSION_NONE) {
                 nBytes = ReadCharData(mat,(char*)matvar->data,packed_type,len);
                 /*
@@ -6827,52 +6866,65 @@ Mat_VarReadNextInfo5( mat_t *mat )
             }
             if ( matvar->class_type != MAT_C_OPAQUE ) {
                 /* Inflate dimensions */
-                bytesread += InflateDimensions(mat,matvar,uncomp_buf);
+                mat_uint32_t* dims = NULL;
+                int do_clean = 0;
+                bytesread += InflateRankDims(mat,matvar,uncomp_buf,sizeof(uncomp_buf),&dims);
+                if ( NULL == dims )
+                    dims = uncomp_buf + 2;
+                else
+                    do_clean = 1;
                 if ( mat->byteswap ) {
                     (void)Mat_uint32Swap(uncomp_buf);
                     (void)Mat_uint32Swap(uncomp_buf+1);
                 }
                 /* Rank and dimension */
                 if ( uncomp_buf[0] == MAT_T_INT32 ) {
+                    int j;
                     nbytes = uncomp_buf[1];
                     matvar->rank = nbytes / 4;
                     matvar->dims = (size_t*)malloc(matvar->rank*sizeof(*matvar->dims));
                     if ( mat->byteswap ) {
-                        for ( i = 0; i < matvar->rank; i++ )
-                            matvar->dims[i] = Mat_uint32Swap(&(uncomp_buf[2+i]));
+                        for ( j = 0; j < matvar->rank; j++ )
+                            matvar->dims[j] = Mat_uint32Swap(dims + j);
                     } else {
-                        for ( i = 0; i < matvar->rank; i++ )
-                            matvar->dims[i] = uncomp_buf[2+i];
+                        for ( j = 0; j < matvar->rank; j++ )
+                            matvar->dims[j] = dims[j];
                     }
                 }
+                if ( do_clean )
+                    free(dims);
                 /* Inflate variable name tag */
                 bytesread += InflateVarNameTag(mat,matvar,uncomp_buf);
                 if ( mat->byteswap )
                     (void)Mat_uint32Swap(uncomp_buf);
                 /* Name of variable */
                 if ( uncomp_buf[0] == MAT_T_INT8 ) {    /* Name not in tag */
-                    int len;
+                    mat_uint32_t len, len_pad;
                     if ( mat->byteswap )
                         len = Mat_uint32Swap(uncomp_buf+1);
                     else
                         len = uncomp_buf[1];
 
                     if ( len % 8 == 0 )
-                        i = len;
+                        len_pad = len;
                     else
-                        i = len+(8-(len % 8));
-                    matvar->name = (char*)malloc(i+1);
-                    /* Inflate variable name */
-                    bytesread += InflateVarName(mat,matvar,matvar->name,i);
-                    matvar->name[len] = '\0';
-                } else if ( ((uncomp_buf[0] & 0x0000ffff) == MAT_T_INT8) &&
-                            ((uncomp_buf[0] & 0xffff0000) != 0x00) ) {
-                    /* Name packed in tag */
-                    int len;
-                    len = (uncomp_buf[0] & 0xffff0000) >> 16;
-                    matvar->name = (char*)malloc(len+1);
-                    memcpy(matvar->name,uncomp_buf+1,len);
-                    matvar->name[len] = '\0';
+                        len_pad = len + 8 - (len % 8);
+                    matvar->name = (char*)malloc(len_pad + 1);
+                    if ( NULL != matvar->name ) {
+                        /* Inflate variable name */
+                        bytesread += InflateVarName(mat,matvar,matvar->name,len_pad);
+                        matvar->name[len] = '\0';
+                    }
+                } else {
+                    mat_uint32_t len = (uncomp_buf[0] & 0xffff0000) >> 16;
+                    if ( ((uncomp_buf[0] & 0x0000ffff) == MAT_T_INT8) && len > 0 && len <= 4 ) {
+                        /* Name packed in tag */
+                        matvar->name = (char*)malloc(len+1);
+                        if ( NULL != matvar->name ) {
+                            memcpy(matvar->name,uncomp_buf+1,len);
+                            matvar->name[len] = '\0';
+                        }
+                    }
                 }
                 if ( matvar->class_type == MAT_C_STRUCT )
                     (void)ReadNextStructField(mat,matvar);
@@ -6951,30 +7003,37 @@ Mat_VarReadNextInfo5( mat_t *mat )
                 (void)Mat_uint32Swap(buf);
             /* Name of variable */
             if ( buf[0] == MAT_T_INT8 ) {    /* Name not in tag */
-                int len;
-
+                mat_uint32_t len, len_pad;
                 if ( mat->byteswap )
                     len = Mat_uint32Swap(buf+1);
                 else
                     len = buf[1];
                 if ( len % 8 == 0 )
-                    i = len;
+                    len_pad = len;
                 else
-                    i = len+(8-(len % 8));
-                bytesread+=fread(buf,1,i,(FILE*)mat->fp);
-
-                matvar->name = (char*)malloc(len+1);
-                memcpy(matvar->name,buf,len);
-                matvar->name[len] = '\0';
-            } else if ( ((buf[0] & 0x0000ffff) == MAT_T_INT8) &&
-                        ((buf[0] & 0xffff0000) != 0x00) ) {
-                /* Name packed in the tag */
-                int len;
-
-                len = (buf[0] & 0xffff0000) >> 16;
-                matvar->name = (char*)malloc(len+1);
-                memcpy(matvar->name,buf+1,len);
-                matvar->name[len] = '\0';
+                    len_pad = len + 8 - (len % 8);
+                matvar->name = (char*)malloc(len_pad + 1);
+                if ( NULL != matvar->name ) {
+                    size_t readresult = fread(matvar->name,1,len_pad,(FILE*)mat->fp);
+                    bytesread += readresult;
+                    if ( readresult == len_pad) {
+                        matvar->name[len] = '\0';
+                    } else {
+                        free(matvar->name);
+                        matvar->name = NULL;
+                        Mat_Critical("An error occurred in reading the MAT file");
+                    }
+                }
+            } else {
+                mat_uint32_t len = (buf[0] & 0xffff0000) >> 16;
+                if ( ((buf[0] & 0x0000ffff) == MAT_T_INT8) && len > 0 && len <= 4 ) {
+                    /* Name packed in tag */
+                    matvar->name = (char*)malloc(len+1);
+                    if ( NULL != matvar->name ) {
+                        memcpy(matvar->name,buf+1,len);
+                        matvar->name[len] = '\0';
+                    }
+                }
             }
             if ( matvar->class_type == MAT_C_STRUCT )
                 (void)ReadNextStructField(mat,matvar);
--- a/src/matio_private.h
+++ b/src/matio_private.h
@@ -211,7 +211,7 @@ EXTERN size_t InflateSkip2(mat_t *mat, m
 EXTERN size_t InflateSkipData(mat_t *mat,z_streamp z,enum matio_types data_type,int len);
 EXTERN size_t InflateVarTag(mat_t *mat, matvar_t *matvar, void *buf);
 EXTERN size_t InflateArrayFlags(mat_t *mat, matvar_t *matvar, void *buf);
-EXTERN size_t InflateDimensions(mat_t *mat, matvar_t *matvar, void *buf);
+EXTERN size_t InflateRankDims(mat_t *mat, matvar_t *matvar, void *buf, size_t nbytes, mat_uint32_t** dims);
 EXTERN size_t InflateVarNameTag(mat_t *mat, matvar_t *matvar, void *buf);
 EXTERN size_t InflateVarName(mat_t *mat,matvar_t *matvar,void *buf,int N);
 EXTERN size_t InflateDataTag(mat_t *mat, matvar_t *matvar, void *buf);
