Skip to content

Commit

Permalink
WIP: issue tbeu#241: range checking
Browse files Browse the repository at this point in the history
  • Loading branch information
seanm committed Mar 19, 2024
1 parent 492ea83 commit bd39e33
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 24 deletions.
8 changes: 4 additions & 4 deletions src/endian.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
91 changes: 81 additions & 10 deletions src/read_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,31 @@
#if HAVE_ZLIB
#include <zlib.h>
#endif
#include <float.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
#include <time.h>

#define READ_DATA_NOSWAP(T) \
#define READ_DATA_NOSWAP(T, TT, RoundFunc) \
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]; \
val_ = RoundFunc(val_); \
if (val_ >= min_ && val_ <= max_) { \
data[i] = (T)val_; \
} else { \
break; \
} \
} \
} \
} else { \
Expand All @@ -60,7 +70,14 @@
readcount += j; \
if ( j == block_size ) { \
for ( j = 0; j < block_size; j++ ) { \
data[i + j] = (T)v[j]; \
TT val_ = v[j]; \
val_ = RoundFunc(val_); \
if (val_ >= min_ && val_ <= max_) { \
data[i + j] = (T)val_; \
} else { \
err_ = 1; \
break; \
} \
} \
} else { \
err_ = 1; \
Expand All @@ -72,22 +89,37 @@
readcount += j; \
if ( j == len - i ) { \
for ( j = 0; j < len - i; j++ ) { \
data[i + j] = (T)v[j]; \
TT val_ = v[j]; \
val_ = RoundFunc(val_); \
if (val_ >= min_ && val_ <= max_) { \
data[i + j] = (T)val_; \
} else { \
err_ = 1; \
break; \
} \
} \
} \
} \
} \
} while ( 0 )

#define READ_DATA(T, SwapFunc) \
#define READ_DATA(T, TT, SwapFunc, RoundFunc) \
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]); \
swapped_ = RoundFunc(swapped_); \
if (swapped_ >= min_ && swapped_ <= max_) { \
data[i] = (T)swapped_; \
} else { \
break; \
} \
} \
} \
} else { \
Expand All @@ -99,7 +131,14 @@
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]); \
swapped_ = RoundFunc(swapped_); \
if (swapped_ >= min_ && swapped_ <= max_) { \
data[i + j] = (T)swapped_; \
} else { \
err_ = 1; \
break; \
} \
} \
} else { \
err_ = 1; \
Expand All @@ -111,13 +150,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, RoundFunc); \
} \
} while ( 0 )

Expand Down Expand Up @@ -198,6 +243,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
Expand All @@ -208,6 +255,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
Expand All @@ -219,6 +268,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
Expand All @@ -231,6 +282,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
Expand All @@ -242,6 +295,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
Expand All @@ -252,6 +307,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
Expand All @@ -262,6 +319,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
Expand All @@ -272,6 +331,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
Expand All @@ -282,6 +343,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
Expand All @@ -292,6 +355,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
Expand Down Expand Up @@ -360,6 +425,12 @@ ReadCompressedCharData(mat_t *mat, z_streamp z, void *data, enum matio_types dat
}
#endif

static mat_uint16_t
NOP_UINT16(mat_uint16_t value)
{
return value;
}

size_t
ReadCharData(mat_t *mat, void *_data, enum matio_types data_type, size_t len)
{
Expand All @@ -383,7 +454,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, NOP_UINT16);
err = Mul(&nBytes, readcount, data_size);
break;
}
Expand Down
32 changes: 22 additions & 10 deletions src/read_data_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@
#define READ_TYPE_UINT64_DATA CAT(READ_TYPED_FUNC1, UInt64)
#endif /* HAVE_MAT_UINT64_T */

static READ_TYPE
CAT(Round, READ_TYPE)(READ_TYPE value)
{
#if READ_TYPE_TYPE == READ_TYPE_DOUBLE
return round(value);
#elif READ_TYPE_TYPE == READ_TYPE_SINGLE
return roundf(value);
#else
return value;
#endif
}

static size_t
READ_TYPE_DOUBLE_DATA(mat_t *mat, READ_TYPE *data, size_t len)
{
Expand All @@ -56,7 +68,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, CAT(Round, READ_TYPE));
#endif
return readcount;
}
Expand All @@ -77,7 +89,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, CAT(Round, READ_TYPE));
#endif
return readcount;
}
Expand All @@ -98,7 +110,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, CAT(Round, READ_TYPE));
#endif
return readcount;
}
Expand All @@ -119,7 +131,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, CAT(Round, READ_TYPE));
#endif
return readcount;
}
Expand All @@ -140,7 +152,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, CAT(Round, READ_TYPE));
#endif
return readcount;
}
Expand All @@ -161,7 +173,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, CAT(Round, READ_TYPE));
#endif
return readcount;
}
Expand All @@ -176,7 +188,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, CAT(Round, READ_TYPE));
#endif
return readcount;
}
Expand All @@ -191,7 +203,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, CAT(Round, READ_TYPE));
#endif
return readcount;
}
Expand All @@ -213,7 +225,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, CAT(Round, READ_TYPE));
#endif
return readcount;
}
Expand All @@ -236,7 +248,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, CAT(Round, READ_TYPE));
#endif
return readcount;
}
Expand Down

0 comments on commit bd39e33

Please sign in to comment.