[libdvdnav-devel] [Git][videolan/libdvdread][master] 2 commits: ifo_types: add missing defines for some packed structure sizes

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Mon Aug 11 10:09:06 UTC 2025



Jean-Baptiste Kempf pushed to branch master at VideoLAN / libdvdread


Commits:
87a8b3c2 by Steve Lhomme at 2025-08-10T19:53:32+00:00
ifo_types: add missing defines for some packed structure sizes

Since they are packed structures the size in memory of packed data should be
the same no matter the compiler, compiler options or architecture.

- - - - -
9dd63fdc by Steve Lhomme at 2025-08-11T06:46:01+02:00
assert during compilation if packed sizes are not respected

It will not be checked on compilers without static_assert() or not MSVC (ie
non-C11 compilers).

- - - - -


4 changed files:

- configure.ac
- meson.build
- src/dvdread/ifo_types.h
- src/ifo_read.c


Changes:

=====================================
configure.ac
=====================================
@@ -54,6 +54,17 @@ AC_SUBST([DVDREAD_LTVERSION], [$DVDREAD_LT_CURRENT:$DVDREAD_LT_REVISION:$DVDREAD
 
 AC_PROG_CC_C99
 
+dnl C11 static_assert()
+AC_MSG_CHECKING([for _Static_assert])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([], [
+_Static_assert(1, "The impossible happened.");
+])], [
+  AC_MSG_RESULT([yes])
+  AC_DEFINE([HAVE_STATIC_ASSERT], [1], [Define to 1 if _Static_assert is available.])
+], [
+  AC_MSG_RESULT([no])
+])
+
 AC_CHECK_HEADERS_ONCE([sys/param.h limits.h dlfcn.h])
 
 AC_SYS_LARGEFILE


=====================================
meson.build
=====================================
@@ -82,6 +82,7 @@ elif cc.has_function('strerror_s', prefix: '#include <string.h>', args: test_arg
     cdata.set('HAVE_STRERROR_S', 1)
 endif
 
+cdata.set10('HAVE_STATIC_ASSERT', cc.compiles('_Static_assert(1, "The impossible happened.");', name : '_Static_assert'))
 
 # External dependencies and libraries
 


=====================================
src/dvdread/ifo_types.h
=====================================
@@ -65,6 +65,7 @@ typedef struct {
   uint8_t second;
   uint8_t frame_u; /* The two high bits are the frame rate. */
 } ATTRIBUTE_PACKED dvd_time_t;
+#define DVD_TIME_SIZE 4U
 
 /**
  * Type to store per-command data.
@@ -93,6 +94,7 @@ typedef struct {
   unsigned char letterboxed          : 1;
   unsigned char film_mode            : 1;
 } ATTRIBUTE_PACKED video_attr_t;
+#define VIDEO_ATTR_SIZE  2U
 
 /**
  * Audio Attributes.
@@ -126,6 +128,7 @@ typedef struct {
     } surround;
   } ATTRIBUTE_PACKED app_info;
 } ATTRIBUTE_PACKED audio_attr_t;
+#define AUDIO_ATTR_SIZE  8U
 
 
 /**
@@ -157,6 +160,7 @@ typedef struct {
   unsigned char ach4_seBe  : 1;
   uint8_t zero6[19];
 } ATTRIBUTE_PACKED multichannel_ext_t;
+#define MULTICHANNEL_EXT_SIZE  24U
 
 
 /**
@@ -181,6 +185,7 @@ typedef struct {
   uint8_t  lang_extension;
   uint8_t  code_extension;
 } ATTRIBUTE_PACKED subp_attr_t;
+#define SUBP_ATTR_SIZE  6U
 
 
 
@@ -225,6 +230,7 @@ typedef struct {
   uint32_t last_vobu_start_sector;
   uint32_t last_sector;
 } ATTRIBUTE_PACKED cell_playback_t;
+#define CELL_PLAYBACK_SIZE  24U
 
 #define BLOCK_TYPE_NONE         0x0
 #define BLOCK_TYPE_ANGLE_BLOCK  0x1
@@ -242,6 +248,7 @@ typedef struct {
   uint8_t  zero_1;
   uint8_t  cell_nr;
 } ATTRIBUTE_PACKED cell_position_t;
+#define CELL_POSITION_SIZE 4U
 
 /**
  * User Operations.
@@ -277,6 +284,7 @@ typedef struct {
   unsigned char chapter_search_or_play         : 1;
   unsigned char title_or_time_play             : 1; /* 0 */
 } ATTRIBUTE_PACKED user_ops_t;
+#define USER_OPS_SIZE  4U
 
 /**
  * Program Chain Information.
@@ -366,6 +374,7 @@ typedef struct {
   uint32_t start_sector;
   uint32_t last_sector;
 } ATTRIBUTE_PACKED cell_adr_t;
+#define CELL_ADDR_SIZE  12U
 
 /**
  * Cell Address Table.
@@ -438,6 +447,7 @@ typedef struct {
   subp_attr_t  vmgm_subp_attr;
   subp_attr_t  zero_10[27];  /* XXX: how much 'padding' here? */
 } ATTRIBUTE_PACKED vmgi_mat_t;
+#define VMGI_MAT_SIZE 510U
 
 
 
@@ -556,6 +566,7 @@ typedef struct {
   unsigned char chapter_search_or_play    : 1; /* UOP 1 */
   unsigned char title_or_time_play        : 1; /* UOP 0 */
 } ATTRIBUTE_PACKED playback_type_t;
+#define PLAYBACK_TYPE_SIZE 1U
 
 /**
  * Title Information.
@@ -569,6 +580,7 @@ typedef struct {
   uint8_t  vts_ttn;
   uint32_t title_set_sector;
 } ATTRIBUTE_PACKED title_info_t;
+#define TITLE_INFO_SIZE 12U
 
 /**
  * PartOfTitle Search Pointer Table.
@@ -677,6 +689,7 @@ typedef struct {
   char text[12]; /* ended by 0x09 */
 #endif
 } ATTRIBUTE_PACKED txtdt_t;
+#define TXTDT_SIZE 204U
 
 /**
  * Text Data Language Unit. (Incomplete)
@@ -765,6 +778,7 @@ typedef struct {
   multichannel_ext_t vts_mu_audio_attr[8];
   /* XXX: how much 'padding' here, if any? */
 } ATTRIBUTE_PACKED vtsi_mat_t;
+#define VTSI_MAT_SIZE 984U
 
 
 typedef struct {
@@ -880,6 +894,7 @@ typedef struct {
   uint16_t pgcn;
   uint16_t pgn;
 } ATTRIBUTE_PACKED ptt_info_t;
+#define PTT_INFO_SIZE  4U
 
 /**
  * PartOfTitle Information.
@@ -888,6 +903,7 @@ typedef struct {
   uint16_t nr_of_ptts;
   ptt_info_t *ptt;
 } ATTRIBUTE_PACKED ttu_t;
+#define TTU_SIZE 2U
 
 /**
  * PartOfTitle Search Pointer Table.


=====================================
src/ifo_read.c
=====================================
@@ -34,6 +34,18 @@
 #include "dvdread_internal.h"
 #include "dvdread/bitreader.h"
 
+#ifndef HAVE_STATIC_ASSERT
+#if defined(_MSC_VER)
+#include <crtdbg.h>
+#define _Static_assert(x, y)  _STATIC_ASSERT(x)
+#else
+#define _Static_assert(x, y) // packed size checks not supported by this compiler
+#endif
+#endif
+
+#define POINTER_SIZE  sizeof(void*)
+
+
 #ifndef DVD_BLOCK_LEN
 #define DVD_BLOCK_LEN 2048
 #endif
@@ -123,6 +135,68 @@ static inline int DVDFileSeek_( dvd_file_t *dvd_file, uint32_t offset ) {
   return (DVDFileSeek(dvd_file, (int)offset) == (int)offset);
 }
 
+#define STRINGIFY_NAME( z )   STRINGIFY_NAME_( z )
+#define STRINGIFY_NAME_( z ) #z
+
+#define CHECK_STRUCT_SIZE(strt, ptrs, size) \
+  _Static_assert(sizeof(strt)  <= size + ptrs * POINTER_SIZE,  STRINGIFY_NAME(strt) " bigger than " STRINGIFY_NAME(size)); \
+  _Static_assert(sizeof(strt)  >= size + ptrs * POINTER_SIZE,  STRINGIFY_NAME(strt) " smaller than " STRINGIFY_NAME(size))
+
+#define CHECK_STRUCT_SIZE_REF(strt, ptrs, size) \
+  _Static_assert(sizeof(strt)  <= size + ptrs * POINTER_SIZE + sizeof(int),  STRINGIFY_NAME(strt) " bigger than " STRINGIFY_NAME(size)); \
+  _Static_assert(sizeof(strt)  >= size + ptrs * POINTER_SIZE + sizeof(int),  STRINGIFY_NAME(strt) " smaller than " STRINGIFY_NAME(size))
+
+/* size checks on packed structures */
+CHECK_STRUCT_SIZE(dvd_time_t,             0, DVD_TIME_SIZE);
+CHECK_STRUCT_SIZE(vm_cmd_t,               0, COMMAND_DATA_SIZE);
+CHECK_STRUCT_SIZE(video_attr_t,           0, VIDEO_ATTR_SIZE);
+CHECK_STRUCT_SIZE(audio_attr_t,           0, AUDIO_ATTR_SIZE);
+CHECK_STRUCT_SIZE(multichannel_ext_t,     0, MULTICHANNEL_EXT_SIZE);
+CHECK_STRUCT_SIZE(subp_attr_t,            0, SUBP_ATTR_SIZE);
+CHECK_STRUCT_SIZE(pgc_command_tbl_t,      3, PGC_COMMAND_TBL_SIZE);
+CHECK_STRUCT_SIZE(cell_playback_t,        0, CELL_PLAYBACK_SIZE);
+CHECK_STRUCT_SIZE(cell_position_t,        0, CELL_POSITION_SIZE);
+CHECK_STRUCT_SIZE(user_ops_t,             0, USER_OPS_SIZE);
+CHECK_STRUCT_SIZE_REF(pgc_t,              4, PGC_SIZE);
+CHECK_STRUCT_SIZE(pgci_srp_t,             1, PGCI_SRP_SIZE);
+CHECK_STRUCT_SIZE_REF(pgcit_t,            1, PGCIT_SIZE);
+CHECK_STRUCT_SIZE(pgci_lu_t,              1, PGCI_LU_SIZE);
+CHECK_STRUCT_SIZE(pgci_ut_t,              1, PGCI_UT_SIZE);
+CHECK_STRUCT_SIZE(cell_adr_t,             0, CELL_ADDR_SIZE);
+CHECK_STRUCT_SIZE(c_adt_t,                1, C_ADT_SIZE);
+CHECK_STRUCT_SIZE(vobu_admap_t,           1, VOBU_ADMAP_SIZE);
+CHECK_STRUCT_SIZE(vmgi_mat_t,             0, VMGI_MAT_SIZE);
+
+CHECK_STRUCT_SIZE(playback_type_t,        0, PLAYBACK_TYPE_SIZE);
+CHECK_STRUCT_SIZE(title_info_t,           0, TITLE_INFO_SIZE);
+CHECK_STRUCT_SIZE(tt_srpt_t,              1, TT_SRPT_SIZE);
+CHECK_STRUCT_SIZE(ptl_mait_country_t,     1, PTL_MAIT_COUNTRY_SIZE);
+CHECK_STRUCT_SIZE(ptl_mait_t,             1, PTL_MAIT_SIZE);
+CHECK_STRUCT_SIZE(vts_attributes_t,       0, VTS_ATTRIBUTES_SIZE);
+
+CHECK_STRUCT_SIZE(vts_atrt_t,             2, VTS_ATRT_SIZE);
+CHECK_STRUCT_SIZE(txtdt_t,                0, TXTDT_SIZE);
+CHECK_STRUCT_SIZE(txtdt_lu_t,             1, TXTDT_LU_SIZE);
+CHECK_STRUCT_SIZE(txtdt_mgi_t,            1, TXTDT_MGI_SIZE);
+CHECK_STRUCT_SIZE(vtsi_mat_t,             0, VTSI_MAT_SIZE);
+CHECK_STRUCT_SIZE(ptt_info_t,             0, PTT_INFO_SIZE);
+CHECK_STRUCT_SIZE(ttu_t,                  1, TTU_SIZE);
+CHECK_STRUCT_SIZE(vts_ptt_srpt_t,         2, VTS_PTT_SRPT_SIZE);
+CHECK_STRUCT_SIZE(vts_tmap_t,             1, VTS_TMAP_SIZE);
+CHECK_STRUCT_SIZE(vts_tmapt_t,            2, VTS_TMAPT_SIZE);
+CHECK_STRUCT_SIZE(samg_chapter_t,         0, SAMG_CHAPTER_SIZE);
+CHECK_STRUCT_SIZE(samg_mat_t,             1, SAMG_MAT_SIZE);
+CHECK_STRUCT_SIZE(amgi_mat_t,             0, AMGI_MAT_SIZE);
+CHECK_STRUCT_SIZE(track_info_t,           0, TRACK_INFO_SIZE);
+CHECK_STRUCT_SIZE(tracks_info_table_t,    1, TRACKS_INFO_TABLE_SIZE);
+CHECK_STRUCT_SIZE(atsi_record_t,          0, ATSI_RECORD_SIZE);
+CHECK_STRUCT_SIZE(atsi_mat_t,             0, ATSI_MAT_SIZE);
+CHECK_STRUCT_SIZE(atsi_title_index_t,     0, ATSI_TITLE_INDEX_SIZE);
+CHECK_STRUCT_SIZE(atsi_track_timestamp_t, 0, ATSI_TRACK_TIMESTAMP_SIZE);
+CHECK_STRUCT_SIZE(atsi_track_pointer_t,   0, ATSI_TRACK_POINTER_SIZE);
+CHECK_STRUCT_SIZE(atsi_title_record_t,    2, ATSI_TITLE_ROW_TABLE_SIZE);
+CHECK_STRUCT_SIZE(atsi_title_table_t,     2, ATSI_TITLE_TABLE_SIZE);
+
 static void read_video_attr(video_attr_t *va) {
   getbits_state_t state;
   uint8_t buf[sizeof(video_attr_t)];



View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/eaa62b88f08bffc68b941f3c01938a5567aa30ef...9dd63fdc7d4fd10b0c3ce462219b222d2bd9186c

-- 
View it on GitLab: https://code.videolan.org/videolan/libdvdread/-/compare/eaa62b88f08bffc68b941f3c01938a5567aa30ef...9dd63fdc7d4fd10b0c3ce462219b222d2bd9186c
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the libdvdnav-devel mailing list