Skip to content

Commit

Permalink
Fix reading all-zero sparse array
Browse files Browse the repository at this point in the history
As reported by #250
  • Loading branch information
tbeu committed Jun 16, 2024
1 parent 1a677de commit 9befe4c
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 65 deletions.
133 changes: 75 additions & 58 deletions src/mat4.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,44 +365,46 @@ Mat_VarRead4(mat_t *mat, matvar_t *matvar)

/* matvar->dims[1] either is 3 for real or 4 for complex sparse */
matvar->isComplex = matvar->dims[1] == 4 ? 1 : 0;
if ( matvar->dims[0] < 2 ) {
if ( 0 == matvar->dims[0] ) {
return MATIO_E_FILE_FORMAT_VIOLATION;
}
sparse = (mat_sparse_t *)matvar->data;
sparse->nir = (mat_uint32_t)(matvar->dims[0] - 1);
sparse->nzmax = sparse->nir;
err = Mul(&readcount, sparse->nir, sizeof(mat_uint32_t));
if ( err ) {
Mat_Critical("Integer multiplication overflow");
return err;
}
sparse->ir = (mat_uint32_t *)malloc(readcount);
if ( sparse->ir != NULL ) {
readcount = ReadUInt32Data(mat, sparse->ir, data_type, sparse->nir);
if ( readcount != sparse->nir ) {
free(sparse->ir);
free(matvar->data);
matvar->data = NULL;
return MATIO_E_FILE_FORMAT_VIOLATION;
if ( sparse->nir > 0 ) {
err = Mul(&readcount, sparse->nir, sizeof(mat_uint32_t));
if ( err ) {
Mat_Critical("Integer multiplication overflow");
return err;
}
for ( i = 0; i < sparse->nir; i++ ) {
if ( 0 == sparse->ir[i] ) {
err = MATIO_E_FILE_FORMAT_VIOLATION;
break;
sparse->ir = (mat_uint32_t *)malloc(readcount);
if ( sparse->ir != NULL ) {
readcount = ReadUInt32Data(mat, sparse->ir, data_type, sparse->nir);
if ( readcount != sparse->nir ) {
free(sparse->ir);
free(matvar->data);
matvar->data = NULL;
return MATIO_E_FILE_FORMAT_VIOLATION;
}
sparse->ir[i] = sparse->ir[i] - 1;
}
if ( err ) {
free(sparse->ir);
for ( i = 0; i < sparse->nir; i++ ) {
if ( 0 == sparse->ir[i] ) {
err = MATIO_E_FILE_FORMAT_VIOLATION;
break;
}
sparse->ir[i] = sparse->ir[i] - 1;
}
if ( err ) {
free(sparse->ir);
free(matvar->data);
matvar->data = NULL;
return err;
}
} else {
free(matvar->data);
matvar->data = NULL;
return err;
Mat_Critical("Couldn't allocate memory for the sparse row array");
return MATIO_E_OUT_OF_MEMORY;
}
} else {
free(matvar->data);
matvar->data = NULL;
Mat_Critical("Couldn't allocate memory for the sparse row array");
return MATIO_E_OUT_OF_MEMORY;
}
readcount = ReadDoubleData(mat, &tmp, data_type, 1);
if ( readcount != 1 || tmp > UINT_MAX - 1 || tmp < 0 ) {
Expand Down Expand Up @@ -446,49 +448,53 @@ Mat_VarRead4(mat_t *mat, matvar_t *matvar)
Mat_Critical("Integer multiplication overflow");
return err;
}
sparse->jc = (mat_uint32_t *)malloc(readcount);
if ( sparse->jc != NULL ) {
mat_uint32_t *jc;
err = Mul(&readcount, sparse->nir, sizeof(mat_uint32_t));
if ( err ) {
Mat_Critical("Integer multiplication overflow");
return err;
}
jc = (mat_uint32_t *)malloc(readcount);
if ( jc != NULL ) {
mat_uint32_t j = 0;
sparse->jc[0] = 0;
readcount = ReadUInt32Data(mat, jc, data_type, sparse->nir);
if ( readcount != sparse->nir ) {
if ( sparse->nir > 0 ) {
sparse->jc = (mat_uint32_t *)malloc(readcount);
if ( sparse->jc != NULL ) {
mat_uint32_t *jc;
err = Mul(&readcount, sparse->nir, sizeof(mat_uint32_t));
if ( err ) {
Mat_Critical("Integer multiplication overflow");
return err;
}
jc = (mat_uint32_t *)malloc(readcount);
if ( jc != NULL ) {
mat_uint32_t j = 0;
sparse->jc[0] = 0;
readcount = ReadUInt32Data(mat, jc, data_type, sparse->nir);
if ( readcount != sparse->nir ) {
free(jc);
free(sparse->jc);
free(sparse->ir);
free(matvar->data);
matvar->data = NULL;
return MATIO_E_FILE_FORMAT_VIOLATION;
}
for ( i = 1; i < sparse->njc - 1; i++ ) {
while ( j < sparse->nir && jc[j] <= i )
j++;
sparse->jc[i] = j;
}
free(jc);
/* terminating nnz */
sparse->jc[sparse->njc - 1] = sparse->nir;
} else {
free(sparse->jc);
free(sparse->ir);
free(matvar->data);
matvar->data = NULL;
return MATIO_E_FILE_FORMAT_VIOLATION;
}
for ( i = 1; i < sparse->njc - 1; i++ ) {
while ( j < sparse->nir && jc[j] <= i )
j++;
sparse->jc[i] = j;
Mat_Critical("Couldn't allocate memory for the sparse index array");
return MATIO_E_OUT_OF_MEMORY;
}
free(jc);
/* terminating nnz */
sparse->jc[sparse->njc - 1] = sparse->nir;
} else {
free(sparse->jc);
free(sparse->ir);
free(matvar->data);
matvar->data = NULL;
Mat_Critical("Couldn't allocate memory for the sparse index array");
return MATIO_E_OUT_OF_MEMORY;
}
} else {
free(sparse->ir);
free(matvar->data);
matvar->data = NULL;
Mat_Critical("Couldn't allocate memory for the sparse index array");
return MATIO_E_OUT_OF_MEMORY;
sparse->jc = (mat_uint32_t *)calloc(readcount, 1);
}
readcount = ReadDoubleData(mat, &tmp, data_type, 1);
if ( readcount != 1 ) {
Expand Down Expand Up @@ -629,7 +635,7 @@ Mat_VarRead4(mat_t *mat, matvar_t *matvar)
Mat_Critical("Couldn't allocate memory for the complex sparse data");
return MATIO_E_OUT_OF_MEMORY;
}
} else {
} else if ( sparse->ndata > 0 ) {
sparse->data = malloc(sparse->ndata * Mat_SizeOf(data_type));
if ( sparse->data != NULL ) {
#if defined(EXTENDED_SPARSE)
Expand Down Expand Up @@ -721,6 +727,17 @@ Mat_VarRead4(mat_t *mat, matvar_t *matvar)
Mat_Critical("Couldn't allocate memory for the sparse data");
return MATIO_E_OUT_OF_MEMORY;
}
} else {
readcount = ReadDoubleData(mat, &tmp, data_type, 1);
err = readcount != 1;
if ( err ) {
free(sparse->data);
free(sparse->jc);
free(sparse->ir);
free(matvar->data);
matvar->data = NULL;
return MATIO_E_FILE_FORMAT_VIOLATION;
}
}
break;
} else {
Expand Down
21 changes: 14 additions & 7 deletions src/mat5.c
Original file line number Diff line number Diff line change
Expand Up @@ -3720,13 +3720,15 @@ Mat_VarRead5(mat_t *mat, matvar_t *matvar)
Mat_Critical("Integer multiplication overflow");
break;
}
sparse->data = malloc(nbytes);
if ( sparse->data == NULL ) {
err = MATIO_E_OUT_OF_MEMORY;
Mat_Critical("Couldn't allocate memory for the sparse data");
break;
if ( nbytes > 0 ) {
sparse->data = malloc(nbytes);
if ( sparse->data == NULL ) {
err = MATIO_E_OUT_OF_MEMORY;
Mat_Critical("Couldn't allocate memory for the sparse data");
break;
}
}
if ( matvar->compression == MAT_COMPRESSION_NONE ) {
if ( matvar->compression == MAT_COMPRESSION_NONE && nbytes > 0 ) {
#if defined(EXTENDED_SPARSE)
switch ( matvar->data_type ) {
case MAT_T_DOUBLE:
Expand Down Expand Up @@ -3786,7 +3788,7 @@ Mat_VarRead5(mat_t *mat, matvar_t *matvar)
if ( (nBytes % 8) != 0 )
(void)fseeko((FILE *)mat->fp, 8 - (nBytes % 8), SEEK_CUR);
#if HAVE_ZLIB
} else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) {
} else if ( matvar->compression == MAT_COMPRESSION_ZLIB && nbytes > 0 ) {
#if defined(EXTENDED_SPARSE)
switch ( matvar->data_type ) {
case MAT_T_DOUBLE:
Expand Down Expand Up @@ -3855,6 +3857,11 @@ Mat_VarRead5(mat_t *mat, matvar_t *matvar)
nBytes += 4;
if ( (nBytes % 8) != 0 )
err = InflateSkip(mat, matvar->internal->z, 8 - (nBytes % 8), NULL);
} else if ( matvar->compression == MAT_COMPRESSION_ZLIB ) {
if ( data_in_tag )
nBytes = 4;
if ( (nBytes % 8) != 0 )
err = InflateSkip(mat, matvar->internal->z, 8 - (nBytes % 8), NULL);
#endif /* HAVE_ZLIB */
}
}
Expand Down

0 comments on commit 9befe4c

Please sign in to comment.