libudfread | branch: master | Petri Hintukainen <[email protected]> | Tue Jun 21 22:31:24 2016 +0300| [a1bb0009f3d71ad7a830a93c060c6c7ed161551a] | committer: Petri Hintukainen
ecma167: parse AD extent type > http://git.videolan.org/gitweb.cgi/libudfread.git/?a=commit;h=a1bb0009f3d71ad7a830a93c060c6c7ed161551a --- src/ecma167.c | 19 ++++++++++++++----- src/ecma167.h | 9 +++++++++ src/udfread.c | 8 ++++++++ 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/ecma167.c b/src/ecma167.c index 571253d..ab7a5b9 100644 --- a/src/ecma167.c +++ b/src/ecma167.c @@ -72,8 +72,6 @@ void decode_entity_id(const uint8_t *p, struct entity_id *eid) * Part 3: Volume Structure */ -#define AD_LENGTH_MASK 0x3fffffff - /* Descriptor Tag (ECMA 167, 3/7.2) */ enum tag_identifier decode_descriptor_tag(const uint8_t *buf) { @@ -197,10 +195,17 @@ static void _decode_icb_tag(const uint8_t *p, struct icb_tag *tag) tag->flags = _get_u16(p + 18); } +/* Allocation Descriptors */ + +#define AD_LENGTH_MASK 0x3fffffff +#define AD_TYPE(length) ((length) >> 30) + /* Short Allocation Descriptor (ECMA 167, 4/14.14.1) */ static void _decode_short_ad(const uint8_t *buf, uint16_t partition, struct long_ad *ad) { - ad->length = _get_u32(buf + 0) & AD_LENGTH_MASK; + uint32_t u32 = _get_u32(buf + 0); + ad->extent_type = AD_TYPE(u32); + ad->length = u32 & AD_LENGTH_MASK; ad->lba = _get_u32(buf + 4); ad->partition = partition; } @@ -208,7 +213,9 @@ static void _decode_short_ad(const uint8_t *buf, uint16_t partition, struct long /* Long Allocation Descriptor (ECMA 167, 4/14.14.2) */ void decode_long_ad(const uint8_t *buf, struct long_ad *ad) { - ad->length = _get_u32(buf + 0) & AD_LENGTH_MASK; + uint32_t u32 = _get_u32(buf + 0); + ad->extent_type = AD_TYPE(u32); + ad->length = u32 & AD_LENGTH_MASK; ad->lba = _get_u32(buf + 4); ad->partition = _get_u16(buf + 8); } @@ -216,7 +223,9 @@ void decode_long_ad(const uint8_t *buf, struct long_ad *ad) /* Exrtended Allocation Descriptor (ECMA 167, 4/14.14.3) */ static void _decode_extended_ad(const uint8_t *buf, struct long_ad *ad) { - ad->length = _get_u32(buf + 0) & AD_LENGTH_MASK; + uint32_t u32 = _get_u32(buf + 0); + ad->extent_type = AD_TYPE(u32); + ad->length = u32 & AD_LENGTH_MASK; ad->lba = _get_u32(buf + 12); ad->partition = _get_u16(buf + 16); } diff --git a/src/ecma167.h b/src/ecma167.h index d27710e..9300255 100644 --- a/src/ecma167.h +++ b/src/ecma167.h @@ -149,12 +149,21 @@ void decode_logical_volume(const uint8_t *p, struct logical_volume_descriptor *l * Part 4: File Structure */ +enum { + ECMA_AD_EXTENT_NORMAL = 0, /* allocated and recorded file data */ + ECMA_AD_EXTENT_NOT_RECORDED = 1, + ECMA_AD_EXTENT_NOT_ALLOCATED = 2, + ECMA_AD_EXTENT_AD = 3, /* pointer to next extent of allocation descriptors */ +}; + + /* Short/Long/Extended Allocation Descriptor (ECMA 167, 4/14.14.[1,2,3]) */ struct long_ad { uint32_t lba; /* start block, relative to partition start */ uint32_t length; /* in bytes */ uint16_t partition; + uint8_t extent_type; }; void decode_long_ad(const uint8_t *p, struct long_ad *ad); diff --git a/src/udfread.c b/src/udfread.c index 7b27410..4f4cb2c 100644 --- a/src/udfread.c +++ b/src/udfread.c @@ -1359,6 +1359,14 @@ uint32_t udfread_file_lba(UDFFILE *p, uint32_t file_block) const struct long_ad *ad = &fe->data.ad[0]; ad_size = (ad[i].length + UDF_BLOCK_SIZE - 1) / UDF_BLOCK_SIZE; if (file_block < ad_size) { + + if (ad[i].extent_type != ECMA_AD_EXTENT_NORMAL) { + if (ad[i].extent_type == ECMA_AD_EXTENT_AD) { + udf_error("unsupported allocation desriptor: extent type %u\n", ad[i].extent_type); + } + return 0; + } + if (!ad[i].lba) { /* empty file / no allocated space */ return 0; _______________________________________________ libbluray-devel mailing list [email protected] https://mailman.videolan.org/listinfo/libbluray-devel
