static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,

                                 uint64_t end_offset, void **p_feature_table,

                                 Error **errp)

{

    BDRVQcowState *s = bs->opaque;

    QCowExtension ext;

    uint64_t offset;

    int ret;



#ifdef DEBUG_EXT

    printf("qcow2_read_extensions: start=%ld end=%ld\n", start_offset, end_offset);

#endif

    offset = start_offset;

    while (offset < end_offset) {



#ifdef DEBUG_EXT

        /* Sanity check */

        if (offset > s->cluster_size)

            printf("qcow2_read_extension: suspicious offset %lu\n", offset);



        printf("attempting to read extended header in offset %lu\n", offset);

#endif



        ret = bdrv_pread(bs->file, offset, &ext, sizeof(ext));

        if (ret < 0) {

            error_setg_errno(errp, -ret, "qcow2_read_extension: ERROR: "

                             "pread fail from offset %" PRIu64, offset);

            return 1;

        }

        be32_to_cpus(&ext.magic);

        be32_to_cpus(&ext.len);

        offset += sizeof(ext);

#ifdef DEBUG_EXT

        printf("ext.magic = 0x%x\n", ext.magic);

#endif

        if (ext.len > end_offset - offset) {

            error_setg(errp, "Header extension too large");

            return -EINVAL;

        }



        switch (ext.magic) {

        case QCOW2_EXT_MAGIC_END:

            return 0;



        case QCOW2_EXT_MAGIC_BACKING_FORMAT:

            if (ext.len >= sizeof(bs->backing_format)) {

                error_setg(errp, "ERROR: ext_backing_format: len=%" PRIu32

                           " too large (>=%zu)", ext.len,

                           sizeof(bs->backing_format));

                return 2;

            }

            ret = bdrv_pread(bs->file, offset, bs->backing_format, ext.len);

            if (ret < 0) {

                error_setg_errno(errp, -ret, "ERROR: ext_backing_format: "

                                 "Could not read format name");

                return 3;

            }

            bs->backing_format[ext.len] = '\0';

#ifdef DEBUG_EXT

            printf("Qcow2: Got format extension %s\n", bs->backing_format);

#endif

            break;



        case QCOW2_EXT_MAGIC_FEATURE_TABLE:

            if (p_feature_table != NULL) {

                void* feature_table = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature));

                ret = bdrv_pread(bs->file, offset , feature_table, ext.len);

                if (ret < 0) {

                    error_setg_errno(errp, -ret, "ERROR: ext_feature_table: "

                                     "Could not read table");

                    return ret;

                }



                *p_feature_table = feature_table;

            }

            break;



        default:

            /* unknown magic - save it in case we need to rewrite the header */

            {

                Qcow2UnknownHeaderExtension *uext;



                uext = g_malloc0(sizeof(*uext)  + ext.len);

                uext->magic = ext.magic;

                uext->len = ext.len;

                QLIST_INSERT_HEAD(&s->unknown_header_ext, uext, next);



                ret = bdrv_pread(bs->file, offset , uext->data, uext->len);

                if (ret < 0) {

                    error_setg_errno(errp, -ret, "ERROR: unknown extension: "

                                     "Could not read data");

                    return ret;

                }

            }

            break;

        }



        offset += ((ext.len + 7) & ~7);

    }



    return 0;

}

static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,

                                 uint64_t end_offset, void **p_feature_table,

                                 Error **errp)

{

    BDRVQcowState *s = bs->opaque;

    QCowExtension ext;

    uint64_t offset;

    int ret;



#ifdef DEBUG_EXT

    printf("qcow2_read_extensions: start=%ld end=%ld\n", start_offset, end_offset);

#endif

    offset = start_offset;

    while (offset < end_offset) {



#ifdef DEBUG_EXT

        

        if (offset > s->cluster_size)

            printf("qcow2_read_extension: suspicious offset %lu\n", offset);



        printf("attempting to read extended header in offset %lu\n", offset);

#endif



        ret = bdrv_pread(bs->file, offset, &ext, sizeof(ext));

        if (ret < 0) {

            error_setg_errno(errp, -ret, "qcow2_read_extension: ERROR: "

                             "pread fail from offset %" PRIu64, offset);

            return 1;

        }

        be32_to_cpus(&ext.magic);

        be32_to_cpus(&ext.len);

        offset += sizeof(ext);

#ifdef DEBUG_EXT

        printf("ext.magic = 0x%x\n", ext.magic);

#endif

        if (ext.len > end_offset - offset) {

            error_setg(errp, "Header extension too large");

            return -EINVAL;

        }



        switch (ext.magic) {

        case QCOW2_EXT_MAGIC_END:

            return 0;



        case QCOW2_EXT_MAGIC_BACKING_FORMAT:

            if (ext.len >= sizeof(bs->backing_format)) {

                error_setg(errp, "ERROR: ext_backing_format: len=%" PRIu32

                           " too large (>=%zu)", ext.len,

                           sizeof(bs->backing_format));

                return 2;

            }

            ret = bdrv_pread(bs->file, offset, bs->backing_format, ext.len);

            if (ret < 0) {

                error_setg_errno(errp, -ret, "ERROR: ext_backing_format: "

                                 "Could not read format name");

                return 3;

            }

            bs->backing_format[ext.len] = '\0';

#ifdef DEBUG_EXT

            printf("Qcow2: Got format extension %s\n", bs->backing_format);

#endif

            break;



        case QCOW2_EXT_MAGIC_FEATURE_TABLE:

            if (p_feature_table != NULL) {

                void* feature_table = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature));

                ret = bdrv_pread(bs->file, offset , feature_table, ext.len);

                if (ret < 0) {

                    error_setg_errno(errp, -ret, "ERROR: ext_feature_table: "

                                     "Could not read table");

                    return ret;

                }



                *p_feature_table = feature_table;

            }

            break;



        default:

            

            {

                Qcow2UnknownHeaderExtension *uext;



                uext = g_malloc0(sizeof(*uext)  + ext.len);

                uext->magic = ext.magic;

                uext->len = ext.len;

                QLIST_INSERT_HEAD(&s->unknown_header_ext, uext, next);



                ret = bdrv_pread(bs->file, offset , uext->data, uext->len);

                if (ret < 0) {

                    error_setg_errno(errp, -ret, "ERROR: unknown extension: "

                                     "Could not read data");

                    return ret;

                }

            }

            break;

        }



        offset += ((ext.len + 7) & ~7);

    }



    return 0;

}

        if (ext.len > end_offset - offset) {
static int FUNC_0(BlockDriverState *VAR_0, uint64_t VAR_1,

                                 uint64_t VAR_2, void **VAR_3,

                                 Error **VAR_4)

{

    BDRVQcowState *s = VAR_0->opaque;

    QCowExtension ext;

    uint64_t offset;

    int VAR_5;



#ifdef DEBUG_EXT

    printf("FUNC_0: start=%ld end=%ld\n", VAR_1, VAR_2);

#endif

    offset = VAR_1;

    while (offset < VAR_2) {



#ifdef DEBUG_EXT

        

        if (offset > s->cluster_size)

            printf("qcow2_read_extension: suspicious offset %lu\n", offset);



        printf("attempting to read extended header in offset %lu\n", offset);

#endif



        VAR_5 = bdrv_pread(VAR_0->file, offset, &ext, sizeof(ext));

        if (VAR_5 < 0) {

            error_setg_errno(VAR_4, -VAR_5, "qcow2_read_extension: ERROR: "

                             "pread fail from offset %" PRIu64, offset);

            return 1;

        }

        be32_to_cpus(&ext.magic);

        be32_to_cpus(&ext.len);

        offset += sizeof(ext);

#ifdef DEBUG_EXT

        printf("ext.magic = 0x%x\n", ext.magic);

#endif

        if (ext.len > VAR_2 - offset) {

            error_setg(VAR_4, "Header extension too large");

            return -EINVAL;

        }



        switch (ext.magic) {

        case QCOW2_EXT_MAGIC_END:

            return 0;



        case QCOW2_EXT_MAGIC_BACKING_FORMAT:

            if (ext.len >= sizeof(VAR_0->backing_format)) {

                error_setg(VAR_4, "ERROR: ext_backing_format: len=%" PRIu32

                           " too large (>=%zu)", ext.len,

                           sizeof(VAR_0->backing_format));

                return 2;

            }

            VAR_5 = bdrv_pread(VAR_0->file, offset, VAR_0->backing_format, ext.len);

            if (VAR_5 < 0) {

                error_setg_errno(VAR_4, -VAR_5, "ERROR: ext_backing_format: "

                                 "Could not read format name");

                return 3;

            }

            VAR_0->backing_format[ext.len] = '\0';

#ifdef DEBUG_EXT

            printf("Qcow2: Got format extension %s\n", VAR_0->backing_format);

#endif

            break;



        case QCOW2_EXT_MAGIC_FEATURE_TABLE:

            if (VAR_3 != NULL) {

                void* VAR_6 = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature));

                VAR_5 = bdrv_pread(VAR_0->file, offset , VAR_6, ext.len);

                if (VAR_5 < 0) {

                    error_setg_errno(VAR_4, -VAR_5, "ERROR: ext_feature_table: "

                                     "Could not read table");

                    return VAR_5;

                }



                *VAR_3 = VAR_6;

            }

            break;



        default:

            

            {

                Qcow2UnknownHeaderExtension *uext;



                uext = g_malloc0(sizeof(*uext)  + ext.len);

                uext->magic = ext.magic;

                uext->len = ext.len;

                QLIST_INSERT_HEAD(&s->unknown_header_ext, uext, next);



                VAR_5 = bdrv_pread(VAR_0->file, offset , uext->data, uext->len);

                if (VAR_5 < 0) {

                    error_setg_errno(VAR_4, -VAR_5, "ERROR: unknown extension: "

                                     "Could not read data");

                    return VAR_5;

                }

            }

            break;

        }



        offset += ((ext.len + 7) & ~7);

    }



    return 0;

}

static int FUNC_0(BlockDriverState *VAR_0, uint64_t VAR_1,
uint64_t VAR_2, void **VAR_3,
Error **VAR_4)
{ BDRVQcowState *s = VAR_0->opaque; QCowExtension ext; uint64_t offset; int VAR_5; #ifdef DEBUG_EXT
printf("FUNC_0: start=%ld end=%ld\n", VAR_1, VAR_2); #endif
offset = VAR_1; while (offset < VAR_2) { #ifdef DEBUG_EXT
if (offset > s->cluster_size)
printf("qcow2_read_extension: suspicious offset %lu\n", offset); printf("attempting to read extended header in offset %lu\n", offset); #endif
VAR_5 = bdrv_pread(VAR_0->file, offset, &ext, sizeof(ext)); if (VAR_5 < 0) { error_setg_errno(VAR_4, -VAR_5, "qcow2_read_extension: ERROR: "
"pread fail from offset %" PRIu64, offset); return 1; } be32_to_cpus(&ext.magic); be32_to_cpus(&ext.len); offset += sizeof(ext); #ifdef DEBUG_EXT
printf("ext.magic = 0x%x\n", ext.magic); #endif
if (ext.len > VAR_2 - offset) { error_setg(VAR_4, "Header extension too large"); return -EINVAL; } switch (ext.magic) { case QCOW2_EXT_MAGIC_END:
return 0; case QCOW2_EXT_MAGIC_BACKING_FORMAT:
if (ext.len >= sizeof(VAR_0->backing_format)) { error_setg(VAR_4, "ERROR: ext_backing_format: len=%" PRIu32
" too large (>=%zu)", ext.len,
sizeof(VAR_0->backing_format)); return 2; } VAR_5 = bdrv_pread(VAR_0->file, offset, VAR_0->backing_format, ext.len); if (VAR_5 < 0) { error_setg_errno(VAR_4, -VAR_5, "ERROR: ext_backing_format: "
"Could not read format name"); return 3; } VAR_0->backing_format[ext.len] = '\0'; #ifdef DEBUG_EXT
printf("Qcow2: Got format extension %s\n", VAR_0->backing_format); #endif
break; case QCOW2_EXT_MAGIC_FEATURE_TABLE:
if (VAR_3 != NULL) { void* VAR_6 = g_malloc0(ext.len + 2 * sizeof(Qcow2Feature)); VAR_5 = bdrv_pread(VAR_0->file, offset , VAR_6, ext.len); if (VAR_5 < 0) { error_setg_errno(VAR_4, -VAR_5, "ERROR: ext_feature_table: "
"Could not read table"); return VAR_5; } *VAR_3 = VAR_6; } break; default:
{ Qcow2UnknownHeaderExtension *uext; uext = g_malloc0(sizeof(*uext)  + ext.len); uext->magic = ext.magic; uext->len = ext.len; QLIST_INSERT_HEAD(&s->unknown_header_ext, uext, next); VAR_5 = bdrv_pread(VAR_0->file, offset , uext->data, uext->len); if (VAR_5 < 0) { error_setg_errno(VAR_4, -VAR_5, "ERROR: unknown extension: "
"Could not read data"); return VAR_5; } } break; } offset += ((ext.len + 7) & ~7); } return 0; }