Skip to content

Commit

Permalink
WIP: issue #241: range checking
Browse files Browse the repository at this point in the history
  • Loading branch information
seanm committed Mar 5, 2024
1 parent 492ea83 commit 1a57b16
Show file tree
Hide file tree
Showing 3 changed files with 82 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
78 changes: 68 additions & 10 deletions src/read_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,30 @@
#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) \
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 { \
Expand All @@ -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; \
Expand All @@ -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 { \
Expand All @@ -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; \
Expand All @@ -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 )

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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;
}
Expand Down
20 changes: 10 additions & 10 deletions src/read_data_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down

0 comments on commit 1a57b16

Please sign in to comment.