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:
@@ -498,11 +498,20 @@ struct logvol_integrity_desc_s
|
|||||||
udf_extent_ad_t next_integrity_ext;
|
udf_extent_ad_t next_integrity_ext;
|
||||||
udf_Uint8_t logvol_contents_use[32];
|
udf_Uint8_t logvol_contents_use[32];
|
||||||
udf_Uint32_t i_partitions;
|
udf_Uint32_t i_partitions;
|
||||||
udf_Uint32_t imp_use_len;
|
union { /* Same MSVC workaround as with struct udf_fileid_desc_s */
|
||||||
union { /* MSVC workaround for multiple zero sized arrays */
|
udf_Uint32_t imp_use_len;
|
||||||
udf_Uint32_t freespace_table[0];
|
struct {
|
||||||
udf_Uint32_t size_table[0];
|
udf_Uint32_t unused;
|
||||||
udf_Uint8_t imp_use[0];
|
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;
|
} u;
|
||||||
} GNUC_PACKED;
|
} GNUC_PACKED;
|
||||||
|
|
||||||
@@ -572,11 +581,25 @@ struct udf_fileid_desc_s
|
|||||||
udf_Uint8_t file_characteristics;
|
udf_Uint8_t file_characteristics;
|
||||||
udf_Uint8_t i_file_id;
|
udf_Uint8_t i_file_id;
|
||||||
udf_long_ad_t icb;
|
udf_long_ad_t icb;
|
||||||
udf_Uint16_t i_imp_use;
|
/* MSVC workaround for multiple zero sized arrays
|
||||||
union { /* MSVC workaround for multiple zero sized arrays */
|
Unlike what is the case with GNU, and against logic, an union of zero
|
||||||
udf_Uint8_t imp_use[0];
|
sized arrays in the Microsoft world is not zero bytes but one byte!
|
||||||
udf_Uint8_t file_id[0];
|
Thus, for sizeof() to be consistent across platforms, we must use an
|
||||||
udf_Uint8_t padding[0];
|
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;
|
} u;
|
||||||
} GNUC_PACKED;
|
} GNUC_PACKED;
|
||||||
|
|
||||||
@@ -998,6 +1021,7 @@ struct extended_file_entry
|
|||||||
union { /* MSVC workaround for multiple zero sized arrays */
|
union { /* MSVC workaround for multiple zero sized arrays */
|
||||||
udf_Uint8_t ext_attr[0];
|
udf_Uint8_t ext_attr[0];
|
||||||
udf_Uint8_t alloc_descs[0];
|
udf_Uint8_t alloc_descs[0];
|
||||||
|
udf_Uint8_t pad_to_one_block[2048-216];
|
||||||
} u;
|
} u;
|
||||||
} GNUC_PACKED;
|
} GNUC_PACKED;
|
||||||
|
|
||||||
|
|||||||
@@ -634,7 +634,7 @@ udf_readdir(udf_dirent_t *p_udf_dirent)
|
|||||||
/* advance to next File Identifier Descriptor */
|
/* advance to next File Identifier Descriptor */
|
||||||
/* FIXME: need to advance file entry (fe) as well. */
|
/* FIXME: need to advance file entry (fe) as well. */
|
||||||
uint32_t ofs = 4 *
|
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->i_file_id + 3) / 4);
|
||||||
|
|
||||||
p_udf_dirent->fid =
|
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))
|
if (p_udf_dirent->fid && !udf_checktag(&(p_udf_dirent->fid->tag), TAGID_FID))
|
||||||
{
|
{
|
||||||
uint32_t ofs =
|
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->fid->i_file_id + 3) / 4);
|
||||||
|
|
||||||
p_udf_dirent->dir_left -= ofs;
|
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;
|
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
|
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;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (strlen(p_udf_dirent->psz_name) < i_len)
|
if (strlen(p_udf_dirent->psz_name) < i_len)
|
||||||
p_udf_dirent->psz_name = (char *)
|
p_udf_dirent->psz_name = (char *)
|
||||||
realloc(p_udf_dirent->psz_name, sizeof(char)*i_len+1);
|
realloc(p_udf_dirent->psz_name, sizeof(char)*i_len+1);
|
||||||
|
|
||||||
unicode16_decode(p_udf_dirent->fid->u.imp_use
|
unicode16_decode(p_udf_dirent->fid->u.imp_use.data
|
||||||
+ p_udf_dirent->fid->i_imp_use,
|
+ p_udf_dirent->fid->u.i_imp_use,
|
||||||
i_len, p_udf_dirent->psz_name);
|
i_len, p_udf_dirent->psz_name);
|
||||||
}
|
}
|
||||||
return p_udf_dirent;
|
return p_udf_dirent;
|
||||||
}
|
}
|
||||||
|
udf_dirent_free(p_udf_dirent);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user