Skip to content

Commit 9e1f0e2

Browse files
committed
use __builtin_memcpy to avoid misaligned pointer casts
1 parent 36b304d commit 9e1f0e2

File tree

1 file changed

+29
-20
lines changed

1 file changed

+29
-20
lines changed

tinyfseq.h

+29-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* libtinyfseq v3.1.0 (2024-02-06)
2+
* libtinyfseq v3.2.0 (2024-05-19)
33
* https://github.com/Cryptkeeper/libtinyfseq
44
* MIT License
55
*
@@ -11,7 +11,7 @@
1111

1212
#include <stdint.h>
1313

14-
#define TINYFSEQ_VERSION "3.1.0"
14+
#define TINYFSEQ_VERSION "3.2.0"
1515

1616
typedef enum tf_err_t {
1717
TF_OK = 0,
@@ -60,10 +60,8 @@ typedef struct tf_header_t {
6060
* @param ep End pointer which upon a successful return will point to the end of the structure within `bd` (may be NULL)
6161
* @return A `TFError` value indicating an error, if any, otherwise `TF_OK`
6262
*/
63-
TFError TFHeader_read(const uint8_t *bd,
64-
int bs,
65-
TFHeader *header,
66-
uint8_t **ep);
63+
TFError
64+
TFHeader_read(const uint8_t *bd, int bs, TFHeader *header, uint8_t **ep);
6765

6866
typedef struct tf_compression_block_t {
6967
uint32_t firstFrameId;
@@ -143,9 +141,11 @@ const char *TFError_string(const TFError err) {
143141
case TF_EINVALID_MAGIC:
144142
return "TF_EINVALID_MAGIC (invalid magic file signature)";
145143
case TF_EINVALID_COMPRESSION_TYPE:
146-
return "TF_EINVALID_COMPRESSION_TYPE (unknown compression identifier)";
144+
return "TF_EINVALID_COMPRESSION_TYPE (unknown compression "
145+
"identifier)";
147146
case TF_EINVALID_BUFFER_SIZE:
148-
return "TF_EINVALID_BUFFER_SIZE (undersized data decoding buffer argument)";
147+
return "TF_EINVALID_BUFFER_SIZE (undersized data decoding buffer "
148+
"argument)";
149149
case TF_EINVALID_VAR_SIZE:
150150
return "TF_EINVALID_VAR_SIZE (invalid variable size in header)";
151151
default:
@@ -174,27 +174,36 @@ TFError TFHeader_read(const uint8_t *const bd,
174174

175175
if (bs < HEADER_SIZE) return TF_EINVALID_BUFFER_SIZE;
176176

177-
if (bd[0] != 'P' || bd[1] != 'S' || bd[2] != 'E' || bd[3] != 'Q') return TF_EINVALID_MAGIC;
177+
if (bd[0] != 'P' || bd[1] != 'S' || bd[2] != 'E' || bd[3] != 'Q')
178+
return TF_EINVALID_MAGIC;
179+
180+
__builtin_memcpy(&header->channelDataOffset, &bd[4],
181+
sizeof(header->channelDataOffset));
182+
183+
header->minorVersion = bd[6];
184+
header->majorVersion = bd[7];
185+
186+
__builtin_memcpy(&header->variableDataOffset, &bd[8],
187+
sizeof(header->variableDataOffset));
188+
__builtin_memcpy(&header->channelCount, &bd[10],
189+
sizeof(header->channelCount));
190+
__builtin_memcpy(&header->frameCount, &bd[14], sizeof(header->frameCount));
178191

179-
header->channelDataOffset = ((uint16_t *) &bd[4])[0];
180-
header->minorVersion = bd[6];
181-
header->majorVersion = bd[7];
182-
header->variableDataOffset = ((uint16_t *) &bd[8])[0];
183-
header->channelCount = ((uint32_t *) &bd[10])[0];
184-
header->frameCount = ((uint32_t *) &bd[14])[0];
185192
header->frameStepTimeMillis = bd[18];
186193

187194
// upper 4 bits contain additional compression block count data that is ignored by tinyfseq
188195
// mask to lower 4 bits to filter only the compression type field
189196
const uint8_t compressionType = bd[20] & 0xF;
190197

191-
if (!TFCompressionType_valid(compressionType)) return TF_EINVALID_COMPRESSION_TYPE;
198+
if (!TFCompressionType_valid(compressionType))
199+
return TF_EINVALID_COMPRESSION_TYPE;
192200

193201
header->compressionType = (TFCompressionType) compressionType;
194202
header->compressionBlockCount = bd[21];
195203

196204
header->channelRangeCount = bd[22];
197-
header->sequenceUid = ((uint64_t *) &bd[24])[0];
205+
206+
__builtin_memcpy(&header->sequenceUid, &bd[24], sizeof(header->sequenceUid));
198207

199208
if (ep) *ep = (uint8_t *) bd + HEADER_SIZE;
200209

@@ -209,8 +218,8 @@ TFError TFCompressionBlock_read(const uint8_t *const bd,
209218

210219
if (bs < COMPRESSION_BLOCK_SIZE) return TF_EINVALID_BUFFER_SIZE;
211220

212-
block->firstFrameId = ((uint32_t *) &bd[0])[0];
213-
block->size = ((uint32_t *) &bd[4])[0];
221+
__builtin_memcpy(&block->firstFrameId, &bd[0], sizeof(block->firstFrameId));
222+
__builtin_memcpy(&block->size, &bd[4], sizeof(block->size));
214223

215224
if (ep) *ep = (uint8_t *) bd + COMPRESSION_BLOCK_SIZE;
216225

@@ -229,7 +238,7 @@ TFError TFVarHeader_read(const uint8_t *const bd,
229238
// an empty variable should be at least 5 bytes
230239
if (bs <= VAR_HEADER_SIZE) return TF_EINVALID_BUFFER_SIZE;
231240

232-
varHeader->size = ((uint16_t *) &bd[0])[0];
241+
__builtin_memcpy(&varHeader->size, &bd[0], sizeof(varHeader->size));
233242

234243
if (varHeader->size <= VAR_HEADER_SIZE) return TF_EINVALID_VAR_SIZE;
235244

0 commit comments

Comments
 (0)