From 1a57b16c1cdcebeaf5052e518d1e5a15e307a148 Mon Sep 17 00:00:00 2001 From: Sean McBride Date: Mon, 4 Mar 2024 18:31:07 -0500 Subject: [PATCH] WIP: issue #241: range checking --- src/endian.c | 8 ++--- src/read_data.c | 78 ++++++++++++++++++++++++++++++++++++++------ src/read_data_impl.h | 20 ++++++------ 3 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/endian.c b/src/endian.c index 1327a3e7..e4a58573 100644 --- a/src/endian.c +++ b/src/endian.c @@ -183,8 +183,8 @@ Mat_uint16Swap(mat_uint16_t *a) /** @brief swap the bytes of a 4 byte single-precision float * @ingroup mat_internal - * @param a pointer to integer to swap - * @return the swapped integer + * @param a pointer to integer? to swap + * @return the swapped integer? */ float Mat_floatSwap(float *a) @@ -205,8 +205,8 @@ Mat_floatSwap(float *a) /** @brief swap the bytes of a 4 or 8 byte double-precision float * @ingroup mat_internal - * @param a pointer to integer to swap - * @return the swapped integer + * @param a pointer to integer? to swap + * @return the swapped integer? */ double Mat_doubleSwap(double *a) diff --git a/src/read_data.c b/src/read_data.c index 762dc95a..fcf2a5a1 100644 --- a/src/read_data.c +++ b/src/read_data.c @@ -34,21 +34,30 @@ #if HAVE_ZLIB #include #endif +#include #include +#include #include #include #include #include #include -#define READ_DATA_NOSWAP(T) \ +#define READ_DATA_NOSWAP(T, TT) \ do { \ + TT min_ = (TT)READ_TYPE_MIN; \ + TT max_ = (TT)READ_TYPE_MAX; \ const size_t block_size = READ_BLOCK_SIZE / data_size; \ if ( len <= block_size ) { \ readcount = fread(v, data_size, len, (FILE *)mat->fp); \ if ( readcount == len ) { \ for ( i = 0; i < len; i++ ) { \ - data[i] = (T)v[i]; \ + TT val_ = v[i]; \ + if (val_ >= min_ && val_ <= max_) { \ + data[i] = (T)val_; \ + } else { \ + break; \ + } \ } \ } \ } else { \ @@ -60,7 +69,12 @@ readcount += j; \ if ( j == block_size ) { \ for ( j = 0; j < block_size; j++ ) { \ - data[i + j] = (T)v[j]; \ + TT val_ = v[j]; \ + if (val_ >= min_ && val_ <= max_) { \ + data[i + j] = (T)val_; \ + } else { \ + break; \ + } \ } \ } else { \ err_ = 1; \ @@ -72,22 +86,34 @@ readcount += j; \ if ( j == len - i ) { \ for ( j = 0; j < len - i; j++ ) { \ - data[i + j] = (T)v[j]; \ + TT val_ = v[j]; \ + if (val_ >= min_ && val_ <= max_) { \ + data[i + j] = (T)val_; \ + } else { \ + break; \ + } \ } \ } \ } \ } \ } while ( 0 ) -#define READ_DATA(T, SwapFunc) \ +#define READ_DATA(T, TT, SwapFunc) \ do { \ + TT min_ = (TT)READ_TYPE_MIN; \ + TT max_ = (TT)READ_TYPE_MAX; \ if ( mat->byteswap ) { \ const size_t block_size = READ_BLOCK_SIZE / data_size; \ if ( len <= block_size ) { \ readcount = fread(v, data_size, len, (FILE *)mat->fp); \ if ( readcount == len ) { \ for ( i = 0; i < len; i++ ) { \ - data[i] = (T)SwapFunc(&v[i]); \ + TT swapped_ = SwapFunc(&v[i]); \ + if (swapped_ >= min_ && swapped_ <= max_) { \ + data[i] = (T)swapped_; \ + } else { \ + break; \ + } \ } \ } \ } else { \ @@ -99,7 +125,13 @@ readcount += j; \ if ( j == block_size ) { \ for ( j = 0; j < block_size; j++ ) { \ - data[i + j] = (T)SwapFunc(&v[j]); \ + TT swapped_ = SwapFunc(&v[j]); \ + if (swapped_ >= min_ && swapped_ <= max_) { \ + data[i + j] = (T)swapped_; \ + } else { \ + err_ = 1; \ + break; \ + } \ } \ } else { \ err_ = 1; \ @@ -111,13 +143,19 @@ readcount += j; \ if ( j == len - i ) { \ for ( j = 0; j < len - i; j++ ) { \ - data[i + j] = (T)SwapFunc(&v[j]); \ + TT swapped_ = SwapFunc(&v[j]); \ + if (swapped_ >= min_ && swapped_ <= max_) { \ + data[i + j] = (T)swapped_; \ + } else { \ + err_ = 1; \ + break; \ + } \ } \ } \ } \ } \ } else { \ - READ_DATA_NOSWAP(T); \ + READ_DATA_NOSWAP(T, TT); \ } \ } while ( 0 ) @@ -198,6 +236,8 @@ #define READ_TYPE_UINT8 10 #define READ_TYPE double +#define READ_TYPE_MIN (-DBL_MAX) +#define READ_TYPE_MAX DBL_MAX #define READ_TYPE_TYPE READ_TYPE_DOUBLE #define READ_TYPED_FUNC1 ReadDoubleData #define READ_TYPED_FUNC2 ReadCompressedDoubleData @@ -208,6 +248,8 @@ #undef READ_TYPED_FUNC2 #define READ_TYPE float +#define READ_TYPE_MIN (-FLT_MAX) +#define READ_TYPE_MAX FLT_MAX #define READ_TYPE_TYPE READ_TYPE_SINGLE #define READ_TYPED_FUNC1 ReadSingleData #define READ_TYPED_FUNC2 ReadCompressedSingleData @@ -219,6 +261,8 @@ #ifdef HAVE_MAT_INT64_T #define READ_TYPE mat_int64_t +#define READ_TYPE_MIN INT64_MIN +#define READ_TYPE_MAX INT64_MAX #define READ_TYPE_TYPE READ_TYPE_INT64 #define READ_TYPED_FUNC1 ReadInt64Data #define READ_TYPED_FUNC2 ReadCompressedInt64Data @@ -231,6 +275,8 @@ #ifdef HAVE_MAT_UINT64_T #define READ_TYPE mat_uint64_t +#define READ_TYPE_MIN 0 +#define READ_TYPE_MAX UINT64_MAX #define READ_TYPE_TYPE READ_TYPE_UINT64 #define READ_TYPED_FUNC1 ReadUInt64Data #define READ_TYPED_FUNC2 ReadCompressedUInt64Data @@ -242,6 +288,8 @@ #endif /* HAVE_MAT_UINT64_T */ #define READ_TYPE mat_int32_t +#define READ_TYPE_MIN INT32_MIN +#define READ_TYPE_MAX INT32_MAX #define READ_TYPE_TYPE READ_TYPE_INT32 #define READ_TYPED_FUNC1 ReadInt32Data #define READ_TYPED_FUNC2 ReadCompressedInt32Data @@ -252,6 +300,8 @@ #undef READ_TYPED_FUNC2 #define READ_TYPE mat_uint32_t +#define READ_TYPE_MIN 0 +#define READ_TYPE_MAX UINT32_MAX #define READ_TYPE_TYPE READ_TYPE_UINT32 #define READ_TYPED_FUNC1 ReadUInt32Data #define READ_TYPED_FUNC2 ReadCompressedUInt32Data @@ -262,6 +312,8 @@ #undef READ_TYPED_FUNC2 #define READ_TYPE mat_int16_t +#define READ_TYPE_MIN INT16_MIN +#define READ_TYPE_MAX INT16_MAX #define READ_TYPE_TYPE READ_TYPE_INT16 #define READ_TYPED_FUNC1 ReadInt16Data #define READ_TYPED_FUNC2 ReadCompressedInt16Data @@ -272,6 +324,8 @@ #undef READ_TYPED_FUNC2 #define READ_TYPE mat_uint16_t +#define READ_TYPE_MIN 0 +#define READ_TYPE_MAX UINT16_MAX #define READ_TYPE_TYPE READ_TYPE_UINT16 #define READ_TYPED_FUNC1 ReadUInt16Data #define READ_TYPED_FUNC2 ReadCompressedUInt16Data @@ -282,6 +336,8 @@ #undef READ_TYPED_FUNC2 #define READ_TYPE mat_int8_t +#define READ_TYPE_MIN INT8_MIN +#define READ_TYPE_MAX INT8_MAX #define READ_TYPE_TYPE READ_TYPE_INT8 #define READ_TYPED_FUNC1 ReadInt8Data #define READ_TYPED_FUNC2 ReadCompressedInt8Data @@ -292,6 +348,8 @@ #undef READ_TYPED_FUNC2 #define READ_TYPE mat_uint8_t +#define READ_TYPE_MIN 0 +#define READ_TYPE_MAX UINT8_MAX #define READ_TYPE_TYPE READ_TYPE_UINT8 #define READ_TYPED_FUNC1 ReadUInt8Data #define READ_TYPED_FUNC2 ReadCompressedUInt8Data @@ -383,7 +441,7 @@ ReadCharData(mat_t *mat, void *_data, enum matio_types data_type, size_t len) size_t i, readcount; mat_uint16_t *data = (mat_uint16_t *)_data; mat_uint16_t v[READ_BLOCK_SIZE / sizeof(mat_uint16_t)]; - READ_DATA(mat_uint16_t, Mat_uint16Swap); + READ_DATA(mat_uint16_t, mat_uint16_t, Mat_uint16Swap); err = Mul(&nBytes, readcount, data_size); break; } diff --git a/src/read_data_impl.h b/src/read_data_impl.h index 63e3db49..e258a390 100644 --- a/src/read_data_impl.h +++ b/src/read_data_impl.h @@ -56,7 +56,7 @@ READ_TYPE_DOUBLE_DATA(mat_t *mat, READ_TYPE *data, size_t len) size_t i; const size_t data_size = sizeof(double); double v[READ_BLOCK_SIZE / sizeof(double)]; - READ_DATA(READ_TYPE, Mat_doubleSwap); + READ_DATA(READ_TYPE, double, Mat_doubleSwap); #endif return readcount; } @@ -77,7 +77,7 @@ READ_TYPE_SINGLE_DATA(mat_t *mat, READ_TYPE *data, size_t len) size_t i; const size_t data_size = sizeof(float); float v[READ_BLOCK_SIZE / sizeof(float)]; - READ_DATA(READ_TYPE, Mat_floatSwap); + READ_DATA(READ_TYPE, float, Mat_floatSwap); #endif return readcount; } @@ -98,7 +98,7 @@ READ_TYPE_INT32_DATA(mat_t *mat, READ_TYPE *data, size_t len) size_t i; const size_t data_size = sizeof(mat_int32_t); mat_int32_t v[READ_BLOCK_SIZE / sizeof(mat_int32_t)]; - READ_DATA(READ_TYPE, Mat_int32Swap); + READ_DATA(READ_TYPE, mat_int32_t, Mat_int32Swap); #endif return readcount; } @@ -119,7 +119,7 @@ READ_TYPE_UINT32_DATA(mat_t *mat, READ_TYPE *data, size_t len) size_t i; const size_t data_size = sizeof(mat_uint32_t); mat_uint32_t v[READ_BLOCK_SIZE / sizeof(mat_uint32_t)]; - READ_DATA(READ_TYPE, Mat_uint32Swap); + READ_DATA(READ_TYPE, mat_uint32_t, Mat_uint32Swap); #endif return readcount; } @@ -140,7 +140,7 @@ READ_TYPE_INT16_DATA(mat_t *mat, READ_TYPE *data, size_t len) size_t i; const size_t data_size = sizeof(mat_int16_t); mat_int16_t v[READ_BLOCK_SIZE / sizeof(mat_int16_t)]; - READ_DATA(READ_TYPE, Mat_int16Swap); + READ_DATA(READ_TYPE, mat_int16_t, Mat_int16Swap); #endif return readcount; } @@ -161,7 +161,7 @@ READ_TYPE_UINT16_DATA(mat_t *mat, READ_TYPE *data, size_t len) size_t i; const size_t data_size = sizeof(mat_uint16_t); mat_uint16_t v[READ_BLOCK_SIZE / sizeof(mat_uint16_t)]; - READ_DATA(READ_TYPE, Mat_uint16Swap); + READ_DATA(READ_TYPE, mat_uint16_t, Mat_uint16Swap); #endif return readcount; } @@ -176,7 +176,7 @@ READ_TYPE_INT8_DATA(mat_t *mat, READ_TYPE *data, size_t len) size_t i; const size_t data_size = sizeof(mat_int8_t); mat_int8_t v[READ_BLOCK_SIZE / sizeof(mat_int8_t)]; - READ_DATA_NOSWAP(READ_TYPE); + READ_DATA_NOSWAP(READ_TYPE, mat_int8_t); #endif return readcount; } @@ -191,7 +191,7 @@ READ_TYPE_UINT8_DATA(mat_t *mat, READ_TYPE *data, size_t len) size_t i; const size_t data_size = sizeof(mat_uint8_t); mat_uint8_t v[READ_BLOCK_SIZE / sizeof(mat_uint8_t)]; - READ_DATA_NOSWAP(READ_TYPE); + READ_DATA_NOSWAP(READ_TYPE, mat_uint8_t); #endif return readcount; } @@ -213,7 +213,7 @@ READ_TYPE_INT64_DATA(mat_t *mat, READ_TYPE *data, size_t len) size_t i; const size_t data_size = sizeof(mat_int64_t); mat_int64_t v[READ_BLOCK_SIZE / sizeof(mat_int64_t)]; - READ_DATA(READ_TYPE, Mat_int64Swap); + READ_DATA(READ_TYPE, mat_int64_t, Mat_int64Swap); #endif return readcount; } @@ -236,7 +236,7 @@ READ_TYPE_UINT64_DATA(mat_t *mat, READ_TYPE *data, size_t len) size_t i; const size_t data_size = sizeof(mat_uint64_t); mat_uint64_t v[READ_BLOCK_SIZE / sizeof(mat_uint64_t)]; - READ_DATA(READ_TYPE, Mat_uint64Swap); + READ_DATA(READ_TYPE, mat_uint64_t, Mat_uint64Swap); #endif return readcount; }