libextractor

GNU libextractor
Log | Files | Refs | Submodules | README | LICENSE

commit cfc77bb0a8bbecafc760096463680cc273a0c82a
parent 7587479919bef5cfaddebc4f2ce5bbecfe0c76c2
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 29 Jul 2026 11:09:05 +0200

ensure struct is packed correctly

Diffstat:
Msrc/plugins/qt_extractor.c | 68+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 59 insertions(+), 9 deletions(-)

diff --git a/src/plugins/qt_extractor.c b/src/plugins/qt_extractor.c @@ -35,6 +35,7 @@ #include <zlib.h> #include <stdint.h> #include <stdbool.h> +#include "le_architecture.h" /** * Maximum size (in bytes) of a single top-level atom that we are willing @@ -480,11 +481,19 @@ static ITTagConversionEntry it_to_extr_table[] = { }; +/* The structs below describe on-disk layout and are overlaid directly + on the (unaligned) read buffer, so they must be packed: without that + the compiler is entitled to assume natural alignment and emit loads + that are undefined for the addresses they are actually used at -- and + fatal on a strict-alignment target. The attribute goes on the struct + rather than on each member because gcc ignores it on aggregate and + array members. */ +LE_NETWORK_STRUCT_BEGIN struct Atom { uint32_t size; uint32_t type; -}; +} LE_PACKED; struct LongAtom @@ -492,7 +501,8 @@ struct LongAtom uint32_t one; uint32_t type; uint64_t size; -}; +} LE_PACKED; +LE_NETWORK_STRUCT_END static uint64_t @@ -507,6 +517,40 @@ ntohll (uint64_t n) /** + * Read a big-endian 32 bit value from @a p, which need not be aligned. + * Casting the read buffer to `uint32_t *' has the same alignment problem + * as an unpacked struct does and is not fixed by packing. + * + * @param p (unaligned) source + * @return the value in host byte order + */ +static uint32_t +read_be32 (const void *p) +{ + uint32_t v; + + memcpy (&v, p, sizeof (v)); + return ntohl (v); +} + + +/** + * Read a big-endian 64 bit value from @a p, which need not be aligned. + * + * @param p (unaligned) source + * @return the value in host byte order + */ +static uint64_t +read_be64 (const void *p) +{ + uint64_t v; + + memcpy (&v, p, sizeof (v)); + return ntohll (v); +} + + +/** * Check if at position pos there is a valid atom. * @return false if the atom is invalid, true if it is valid */ @@ -750,6 +794,7 @@ moovHandler (const char *input, /* see http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap1/chapter_2_section_5.html */ +LE_NETWORK_STRUCT_BEGIN struct FileType { struct Atom header; @@ -759,7 +804,8 @@ struct FileType unsigned int version; /* compatible brands */ char compatibility[4]; -}; +} LE_PACKED; +LE_NETWORK_STRUCT_END static int @@ -823,8 +869,8 @@ mvhdHandler (const char *input, timeScale(4) duration(4) ... */ if (asize < hdr + 20) return -1; - timeScale = ntohl (*(const uint32_t *) &body[12]); - duration = ntohl (*(const uint32_t *) &body[16]); + timeScale = read_be32 (&body[12]); + duration = read_be32 (&body[16]); } else if (1 == version) { @@ -832,8 +878,8 @@ mvhdHandler (const char *input, timeScale(4) duration(8) ... */ if (asize < hdr + 32) return -1; - timeScale = ntohl (*(const uint32_t *) &body[20]); - duration = ntohll (*(const uint64_t *) &body[24]); + timeScale = read_be32 (&body[20]); + duration = read_be64 (&body[24]); } else { @@ -852,6 +898,7 @@ mvhdHandler (const char *input, } +LE_NETWORK_STRUCT_BEGIN struct CompressedMovieHeaderAtom { struct Atom cmovAtom; @@ -859,7 +906,8 @@ struct CompressedMovieHeaderAtom char compressor[4]; struct Atom cmvdAtom; uint32_t decompressedSize; -}; +} LE_PACKED; +LE_NETWORK_STRUCT_END static int @@ -1014,12 +1062,14 @@ metaHandler (const char *input, } +LE_NETWORK_STRUCT_BEGIN struct InternationalText { struct Atom header; uint16_t length; uint16_t language; -}; +} LE_PACKED; +LE_NETWORK_STRUCT_END /*