Apply MSVC compatibility workaround to ecma_167.h

* An union of empty arrays is not size zero in MSVC
* this causes issues with various sections of the UDF code that
  use sizeof and can prevent structures from being read properly
* group empty array unions with at least one non zero-sized member
This commit is contained in:
Pete Batard
2012-03-05 18:08:03 +00:00
parent a7d3059857
commit d7296d5ec0
2 changed files with 42 additions and 15 deletions

View File

@@ -498,11 +498,20 @@ struct logvol_integrity_desc_s
udf_extent_ad_t next_integrity_ext;
udf_Uint8_t logvol_contents_use[32];
udf_Uint32_t i_partitions;
udf_Uint32_t imp_use_len;
union { /* MSVC workaround for multiple zero sized arrays */
udf_Uint32_t freespace_table[0];
udf_Uint32_t size_table[0];
udf_Uint8_t imp_use[0];
union { /* Same MSVC workaround as with struct udf_fileid_desc_s */
udf_Uint32_t imp_use_len;
struct {
udf_Uint32_t unused;
udf_Uint32_t data[0];
} freespace_table;
struct {
udf_Uint32_t unused;
udf_Uint32_t data[0];
} size_table;
struct {
udf_Uint32_t unused;
udf_Uint32_t data[0];
} imp_use;
} u;
} GNUC_PACKED;
@@ -572,11 +581,25 @@ struct udf_fileid_desc_s
udf_Uint8_t file_characteristics;
udf_Uint8_t i_file_id;
udf_long_ad_t icb;
udf_Uint16_t i_imp_use;
union { /* MSVC workaround for multiple zero sized arrays */
udf_Uint8_t imp_use[0];
udf_Uint8_t file_id[0];
udf_Uint8_t padding[0];
/* MSVC workaround for multiple zero sized arrays
Unlike what is the case with GNU, and against logic, an union of zero
sized arrays in the Microsoft world is not zero bytes but one byte!
Thus, for sizeof() to be consistent across platforms, we must use an
ugly workaround that attaches the union to the last non-zero member. */
union {
udf_Uint16_t i_imp_use;
struct {
udf_Uint16_t unused;
udf_Uint8_t data[0];
} imp_use;
struct {
udf_Uint16_t unused;
udf_Uint8_t data[0];
} file_id;
struct {
udf_Uint16_t unused;
udf_Uint8_t data[0];
} padding;
} u;
} GNUC_PACKED;
@@ -998,6 +1021,7 @@ struct extended_file_entry
union { /* MSVC workaround for multiple zero sized arrays */
udf_Uint8_t ext_attr[0];
udf_Uint8_t alloc_descs[0];
udf_Uint8_t pad_to_one_block[2048-216];
} u;
} GNUC_PACKED;

View File

@@ -634,7 +634,7 @@ udf_readdir(udf_dirent_t *p_udf_dirent)
/* advance to next File Identifier Descriptor */
/* FIXME: need to advance file entry (fe) as well. */
uint32_t ofs = 4 *
((sizeof(*(p_udf_dirent->fid)) + p_udf_dirent->fid->i_imp_use
((sizeof(*(p_udf_dirent->fid)) + p_udf_dirent->fid->u.i_imp_use
+ p_udf_dirent->fid->i_file_id + 3) / 4);
p_udf_dirent->fid =
@@ -661,7 +661,7 @@ udf_readdir(udf_dirent_t *p_udf_dirent)
if (p_udf_dirent->fid && !udf_checktag(&(p_udf_dirent->fid->tag), TAGID_FID))
{
uint32_t ofs =
4 * ((sizeof(*p_udf_dirent->fid) + p_udf_dirent->fid->i_imp_use
4 * ((sizeof(*p_udf_dirent->fid) + p_udf_dirent->fid->u.i_imp_use
+ p_udf_dirent->fid->i_file_id + 3) / 4);
p_udf_dirent->dir_left -= ofs;
@@ -674,19 +674,22 @@ udf_readdir(udf_dirent_t *p_udf_dirent)
const unsigned int i_len = p_udf_dirent->fid->i_file_id;
if (DRIVER_OP_SUCCESS != udf_read_sectors(p_udf, &p_udf_dirent->fe, p_udf->i_part_start
+ p_udf_dirent->fid->icb.loc.lba, 1))
+ p_udf_dirent->fid->icb.loc.lba, 1)) {
udf_dirent_free(p_udf_dirent);
return NULL;
}
if (strlen(p_udf_dirent->psz_name) < i_len)
p_udf_dirent->psz_name = (char *)
realloc(p_udf_dirent->psz_name, sizeof(char)*i_len+1);
unicode16_decode(p_udf_dirent->fid->u.imp_use
+ p_udf_dirent->fid->i_imp_use,
unicode16_decode(p_udf_dirent->fid->u.imp_use.data
+ p_udf_dirent->fid->u.i_imp_use,
i_len, p_udf_dirent->psz_name);
}
return p_udf_dirent;
}
udf_dirent_free(p_udf_dirent);
return NULL;
}