qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 03/10] block/dmg: extract processing of resource


From: Peter Wu
Subject: Re: [Qemu-devel] [PATCH 03/10] block/dmg: extract processing of resource forks
Date: Sat, 03 Jan 2015 12:24:40 +0100
User-agent: KMail/4.14.3 (Linux/3.18.1-1-ARCH; KDE/4.14.3; x86_64; ; )

On Friday 02 January 2015 19:01:06 John Snow wrote:
> On 12/27/2014 10:01 AM, Peter Wu wrote:
> > Besides the offset, also read the resource length. This length is now
> > used in the extracted function to verify the end of the resource fork
> > against "count" from the resource fork.
> >
> > Signed-off-by: Peter Wu <address@hidden>
> > ---
> >   block/dmg.c | 90 
> > ++++++++++++++++++++++++++++++++++++++++---------------------
> >   1 file changed, 59 insertions(+), 31 deletions(-)
> >
> > diff --git a/block/dmg.c b/block/dmg.c
> > index 6dc6dbb..7f49388 100644
> > --- a/block/dmg.c
> > +++ b/block/dmg.c
> > @@ -278,38 +278,13 @@ fail:
> >       return ret;
> >   }
> >
> > -static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
> > -                    Error **errp)
> > +static int dmg_read_resource_fork(BlockDriverState *bs, DmgHeaderState *ds,
> > +                                  uint64_t info_begin, uint64_t 
> > info_length)
> >   {
> > -    BDRVDMGState *s = bs->opaque;
> > -    DmgHeaderState ds;
> > -    uint64_t info_begin, info_end;
> > -    uint32_t count, tmp;
> > -    int64_t offset;
> >       int ret;
> > -
> > -    bs->read_only = 1;
> > -    s->n_chunks = 0;
> > -    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> > -    ds.last_in_offset = 0;
> > -    ds.last_out_offset = 0;
> > -    ds.max_compressed_size = 1;
> > -    ds.max_sectors_per_chunk = 1;
> > -
> > -    /* locate the UDIF trailer */
> > -    offset = dmg_find_koly_offset(bs->file);
> > -    if (offset < 0) {
> > -        ret = offset;
> > -        goto fail;
> > -    }
> > -
> > -    ret = read_uint64(bs, offset + 0x28, &info_begin);
> > -    if (ret < 0) {
> > -        goto fail;
> > -    } else if (info_begin == 0) {
> > -        ret = -EINVAL;
> > -        goto fail;
> > -    }
> > +    uint32_t count, tmp;
> > +    uint64_t info_end;
> > +    uint64_t offset;
> >
> >       ret = read_uint32(bs, info_begin, &tmp);
> >       if (ret < 0) {
> > @@ -326,6 +301,10 @@ static int dmg_open(BlockDriverState *bs, QDict 
> > *options, int flags,
> >           ret = -EINVAL;
> >           goto fail;
> >       }
> > +    if (count > info_length) {
> > +        ret = -EINVAL;
> > +        goto fail;
> > +    }
> >       info_end = info_begin + count;
> >
> >       /* begin of mish block */
> > @@ -342,12 +321,61 @@ static int dmg_open(BlockDriverState *bs, QDict 
> > *options, int flags,
> >           }
> >           offset += 4;
> >
> > -        ret = dmg_read_mish_block(bs, &ds, offset, count);
> > +        ret = dmg_read_mish_block(bs, ds, offset, count);
> >           if (ret < 0) {
> >               goto fail;
> >           }
> >           offset += count;
> >       }
> > +    return 0;
> > +
> > +fail:
> > +    return ret;
> > +}
> > +
> > +static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
> > +                    Error **errp)
> > +{
> > +    BDRVDMGState *s = bs->opaque;
> > +    DmgHeaderState ds;
> > +    uint64_t rsrc_fork_offset, rsrc_fork_length;
> > +    int64_t offset;
> > +    int ret;
> > +
> > +    bs->read_only = 1;
> > +    s->n_chunks = 0;
> > +    s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
> > +    ds.last_in_offset = 0;
> > +    ds.last_out_offset = 0;
> > +    ds.max_compressed_size = 1;
> > +    ds.max_sectors_per_chunk = 1;
> > +
> > +    /* locate the UDIF trailer */
> > +    offset = dmg_find_koly_offset(bs->file);
> > +    if (offset < 0) {
> > +        ret = offset;
> > +        goto fail;
> > +    }
> > +
> > +    /* offset of resource fork (RsrcForkOffset) */
> > +    ret = read_uint64(bs, offset + 0x28, &rsrc_fork_offset);
> > +    if (ret < 0) {
> > +        goto fail;
> > +    }
> > +    ret = read_uint64(bs, offset + 0x30, &rsrc_fork_length);
> > +    if (ret < 0) {
> > +        goto fail;
> > +    }
> > +    if (rsrc_fork_offset != 0 && rsrc_fork_length != 0) {
> > +        ret = dmg_read_resource_fork(bs, &ds,
> > +                                     rsrc_fork_offset, rsrc_fork_length);
> > +        if (ret < 0) {
> > +            goto fail;
> > +        }
> > +    } else {
> > +        ret = -EINVAL;
> > +        goto fail;
> > +    }
> >
> >       /* initialize zlib engine */
> >       s->compressed_chunk = qemu_try_blockalign(bs->file,
> >
> 
> I know your refactor hardly touches the code here, but this is a good 
> place to mention it:
> 
>  From what I can tell from the Resource Fork format
> https://developer.apple.com/legacy/library/documentation/mac/pdf/MoreMacintoshToolbox.pdf#page=151
> 
> there are four fields of interest in the header of the resourcefork 
> before we start looping trying to find mish data:
> 
> uint32_t data_offset;
> uint32_t map_offset;
> uint32_t data_length;
> uint32_t map_length;
> 
> We are treating the map which comes right after the data as the "data 
> length" which is not too far from the truth, but may include extra bytes.

The rsrc_fork_offset and rsrc_fork_length values above come from the
trailer, not the resource fork... but now that I read the new function I
see what you mean here. The offset '4' should be '8'. I'll fix this in
v2.

> e.g., in the vlc dmg you linked:
> 
> The koly header advertises a Resource Fork length of 93276 bytes.
> the resource fork itself has a header of:
> 
> data_offset := 256
> map_offset := 92860   // not length!
> data_length := 92604
> map_length := 416
> 
> 
> Since we are naming this function explicitly after the Resource Fork, we 
> should probably tidy this up just a little bit to be clearer at the very 
> least.
> 
> The space reserved for system use, here asserted by QEMU to always be 
> 0x100, is technically variable and perhaps could be adjusted as well 
> with minimal changes.

This artificial restriction looks unnecessary even when there are no
other files in practice. I have replaced it by a saner check for v2.

> A comment pointing to this documentation for the format here would also 
> be helpful, as your other source details koly and mish, but Resource 
> Fork was missing.

I'll mention this in the commit message, thanks!
-- 
Kind regards,
Peter
https://lekensteyn.nl




reply via email to

[Prev in Thread] Current Thread [Next in Thread]