From: Gerhard Sittig Date: Sun, 19 Mar 2023 17:09:30 +0000 (+0100) Subject: libsigrok-internal.h: add length checking endianess helpers X-Git-Url: https://sigrok.org/gitweb/?p=libsigrok.git;a=commitdiff_plain;h=e721b1bfdeceea14fea8470dea9cce5d676e8869 libsigrok-internal.h: add length checking endianess helpers Introduce the read_u8_inc_len() and read_u16le_inc_len() routines which read the respective numbers from binary input, advance the current read position, and also track the remaining length of input data. Call sites need not duplicate the data field width they advanced over. The input stream is considered exhausted when there is insufficient data to read another field. All subsequent reads will also terminate. Calling applications need to check before reading when they expect specific sets of adjacent fields to be available. It is assumed that most call sites already do this (once for the whole input stream, not individually for each conversion call of a field). --- diff --git a/src/libsigrok-internal.h b/src/libsigrok-internal.h index 7499e15f..06c227bb 100644 --- a/src/libsigrok-internal.h +++ b/src/libsigrok-internal.h @@ -615,6 +615,30 @@ static inline uint8_t read_u8_inc(const uint8_t **p) return v; } +/** + * Read unsigned 8bit integer, check length, increment read position. + * @param[in, out] p Pointer into byte stream. + * @param[in, out] l Remaining input payload length. + * @return Retrieved integer value, unsigned. + */ +static inline uint8_t read_u8_inc_len(const uint8_t **p, size_t *l) +{ + uint8_t v; + + if (!p || !*p) + return 0; + if (l && *l < sizeof(v)) { + *l = 0; + return 0; + } + v = read_u8(*p); + *p += sizeof(v); + if (l) + *l -= sizeof(v); + + return v; +} + /** * Read signed 8bit integer from raw memory, increment read position. * @param[in, out] p Pointer into byte stream. @@ -666,6 +690,30 @@ static inline uint16_t read_u16le_inc(const uint8_t **p) return v; } +/** + * Read unsigned 16bit integer (LE format), check length, increment position. + * @param[in, out] p Pointer into byte stream. + * @param[in, out] l Remaining input payload length. + * @return Retrieved integer value, unsigned. + */ +static inline uint16_t read_u16le_inc_len(const uint8_t **p, size_t *l) +{ + uint16_t v; + + if (!p || !*p) + return 0; + if (l && *l < sizeof(v)) { + *l = 0; + return 0; + } + v = read_u16le(*p); + *p += sizeof(v); + if (l) + *l -= sizeof(v); + + return v; +} + /** * Read signed 16bit integer from raw memory (big endian format), increment read position. * @param[in, out] p Pointer into byte stream.