Пример #1
0
/**
 * Takes an initialized asf_file_t structure file as a parameter. Allocates
 * a new asf_object_header_t in file->header and uses the file->iostream to
 * read all fields and subobjects into it. Finally calls the
 * asf_parse_header_validate function to validate the values and parse the
 * commonly used values into the asf_file_t struct itself.
 */
int
asf_parse_header(asf_file_t *file)
{
	asf_object_header_t *header;
	asf_iostream_t *iostream;
	uint8_t hdata[30];
	int tmp;

	file->header = NULL;
	iostream = &file->iostream;

	/* object minimum is 24 bytes and header needs to have
	 * the subobject count field and two reserved fields */
	tmp = asf_byteio_read(iostream, hdata, 30);
	if (tmp < 0) {
		/* not enough data to read the header object */
		return tmp;
	}

	file->header = malloc(sizeof(asf_object_header_t));
	header = file->header;
	if (!header) {
		return ASF_ERROR_OUTOFMEM;
	}

	/* read the object and check its size value */
	asf_parse_read_object((asfint_object_t *) header, hdata);
	if (header->size < 30) {
		/* invalid size for header object */
		return ASF_ERROR_INVALID_OBJECT_SIZE;
	}

	/* read header object specific compulsory fields */
	header->subobjects = GetDWLE(hdata + 24);
	header->reserved1 = hdata[28];
	header->reserved2 = hdata[29];

	/* clear header extension object and subobject list */
	header->ext = NULL;
	header->first = NULL;
	header->last = NULL;

	/* the header data needs to be allocated for reading */
	header->datalen = header->size - 30;
	header->data = malloc(header->datalen * sizeof(uint8_t));
	if (!header->data) {
		return ASF_ERROR_OUTOFMEM;
	}

	tmp = asf_byteio_read(iostream, header->data, header->datalen);
	if (tmp < 0) {
		return tmp;
	}

	if (header->subobjects > 0) {
		uint64_t datalen;
		uint8_t *data;
		int i;

		debug_printf("starting to read subobjects");

		/* use temporary variables for use during the read */
		datalen = header->datalen;
		data = header->data;
		for (i=0; i<header->subobjects; i++) {
			asfint_object_t *current;

			if (datalen < 24) {
				/* not enough data for reading object */
				break;
			}

			current = malloc(sizeof(asfint_object_t));
			if (!current) {
				return ASF_ERROR_OUTOFMEM;
			}

			asf_parse_read_object(current, data);
			if (current->size > datalen || current->size < 24) {
				/* invalid object size */
				break;
			}

			/* Check if the current subobject is a header extension
			 * object or just a normal subobject */
			if (current->type == GUID_HEADER_EXTENSION && !header->ext) {
				int ret;
				asf_object_headerext_t *headerext;

				/* we handle header extension separately because it has
				 * some subobjects as well */
				current = realloc(current, sizeof(asf_object_headerext_t));
				headerext = (asf_object_headerext_t *) current;
				headerext->first = NULL;
				headerext->last = NULL;
				ret = asf_parse_headerext(headerext, data, datalen);

				if (ret < 0) {
					/* error parsing header extension */
					return ret;
				}

				header->ext = headerext;
			} else {
				if (current->type == GUID_HEADER_EXTENSION) {
					debug_printf("WARNING! Second header extension object found, ignoring it!");
				}

				current->datalen = current->size - 24;
				current->data = data + 24;

				/* add to list of subobjects */
				if (!header->first) {
					header->first = current;
					header->last = current;
				} else {
					header->last->next = current;
					header->last = current;
				}
			}

			data += current->size;
			datalen -= current->size;
		}

		if (i != header->subobjects || datalen != 0) {
			/* header data size doesn't match given subobject count */
			return ASF_ERROR_INVALID_VALUE;
		}

		debug_printf("%d subobjects read successfully", i);
	}

	tmp = asf_parse_header_validate(file, file->header);
	if (tmp < 0) {
		/* header read ok but doesn't validate correctly */
		return tmp;
	}

	debug_printf("header validated correctly");

	return header->size;
}
Пример #2
0
/**
 * Takes an initialized asf_file_t structure file as a parameter. Allocates
 * a new asf_object_header_t in file->header and uses the file->iostream to
 * read all fields and subobjects into it. Finally calls the
 * asf_parse_header_validate function to validate the values and parse the
 * commonly used values into the asf_file_t struct itself.
 */
int ASFParser::asf_parse_header() {
    asf_object_header_t *header = NULL;
    asf_iostream_t *iostream = NULL;
    uint8_t hdata[30];
    int tmp;

    file->header = NULL;
    iostream = &file->iostream;

    /* object minimum is 24 bytes and header needs to have
     * the subobject count field and two reserved fields */
    memset(hdata, 0, 30);
    tmp = ASFByteIO::asf_byteio_read(hdata, 30, iostream);
    if (tmp < 0) {
        /* not enough data to read the header object */
        ALOGE("asf_parse_header:error 1\n");
        return tmp;
    }

    file->header = (asf_object_header_t*)malloc(sizeof(asf_object_header_t));
    if (!file->header) {
        return ASF_ERROR_OUTOFMEM;
    }
    memset(file->header, 0, sizeof(asf_object_header_t));
    header = file->header;
    /* clear header extension object and subobject list */
    header->ext = NULL;
    header->first = NULL;
    header->last = NULL;

    /* read the object and check its size value */
    asf_parse_read_object((asfint_object_t *) header, hdata);
    if (header->size < 30) {
        /* invalid size for header object */
        ALOGE("asf_parse_header:error 2\n");
        return ASF_ERROR_OBJECT_SIZE;
    }
    /* to check not ASF file type */
    if (header->type == GUID_UNKNOWN) {
        /* invalid GUID for header object */
        return ASF_ERROR_INVALID_VALUE;
    }

    /* read header object specific compulsory fields */
    header->subobjects = ASFByteIO::asf_byteio_getDWLE(hdata + 24);//sub header object number
    header->reserved1 = hdata[28];
    header->reserved2 = hdata[29];
    header->datalen = header->size - 30;

    //seek to Data Object and check if Data Object follows by Header Object
    {
        file->iostream.seek(iostream->source, header->size);
	//read 50B from data_object
	asfint_object_t *data = NULL;
        uint8_t ddata[50];
        int tmp;
        memset(ddata, 0, 50);
        /* object minimum is 24 bytes and data object needs to have
         * 26 additional bytes for its internal fields */
        tmp = ASFByteIO::asf_byteio_read(ddata, 50, iostream);
        if (tmp < 0) {
	    ALOGI("read data 50B error");
            return tmp;
        }

        data = (asfint_object_t*)calloc(1,sizeof(asfint_object_t));
        if (!data) {
            return ASF_ERROR_OUTOFMEM;
        }
        asf_parse_read_object((asfint_object_t *)data, ddata);
        /* read the object and check its size value */
        if (data->size < 50) {
            /* invalid size for data object */
	    ALOGI("ASF Data Object Size Error");
            return ASF_ERROR_OBJECT_SIZE;
        } else if (data->type != GUID_DATA) {
	    ALOGE("Data Object Not follow by Header Object");
	    return ASF_ERROR_INVALID_OBJECT;
	}
    } 

    //seek to Header Object's data, and read header->data from iostream
    file->iostream.seek(iostream->source, 30);
    header->data = (uint8_t*)malloc(header->datalen * sizeof(uint8_t));
    if (!header->data) {
        return ASF_ERROR_OUTOFMEM;
    }
    memset(header->data, 0, header->datalen * sizeof(uint8_t));

    tmp = ASFByteIO::asf_byteio_read(header->data, header->datalen, iostream);
    if (tmp < 0) {
        ALOGE("asf_parse_header:error 3\n");
        return tmp;
    }

    if (header->subobjects > 0) {
        uint64_t datalen;
        uint8_t *data = NULL;
        int i;

        ALOGV("starting to read subobjects\n");

        /* use temporary variables for use during the read */
        datalen = header->datalen;
        data = header->data;
        for (i=0; i<header->subobjects; i++) {
            void * tmp = NULL;
            asfint_object_t *current = NULL;

            if (datalen < 24) {//UUID+Size ==24
                /* not enough data for reading object */
                break;
            }


            //current = (asfint_object_t *)oscl_malloc(sizeof(asfint_object_t));
            tmp = (void*)malloc(sizeof(asfint_object_t));
            memset(tmp, 0, sizeof(asfint_object_t));
            current = (asfint_object_t *)tmp;
            if (!current) {
                return ASF_ERROR_OUTOFMEM;
            }

            asf_parse_read_object(current, data);
            if (current->size > datalen || current->size < 24) {
                /* invalid object size */
                ALOGE("invalid object size\n");
                break;
            }

            /* Check if the current subobject is a header extension
             * object or just a normal subobject */
            if (current->type == GUID_HEADER_EXTENSION && !header->ext) {
                int ret;
                asf_object_headerext_t *headerext = NULL;

                /* we handle header extension separately because it has
                 * some subobjects as well */
                //current = (asf_object_headerext_t*)oscl_realloc(current, sizeof(asf_object_headerext_t));
                //headerext = (asf_object_headerext_t *) current;

                //changed by satish to fix compiler conversion problem
                tmp = (void*)realloc(tmp, sizeof(asf_object_headerext_t));
                current = (asfint_object_t *)tmp;
                headerext = (asf_object_headerext_t *) tmp;


                headerext->first = NULL;
                headerext->last = NULL;
                ret = asf_parse_headerext(headerext, data, datalen);

                if (ret < 0) {
                    /* error parsing header extension */
                    return ret;
                }

                header->ext = headerext;
            } else {
                if (current->type == GUID_HEADER_EXTENSION) {
                    ALOGV("WARNING! Second header extension object found, ignoring it!\n");
                }

                current->datalen = current->size - 24;
                current->data = data + 24;

                /* add to list of subobjects */
                if (!header->first) {
                    header->first = current;
                    header->last = current;
                } else {
                    header->last->next = current;
                    header->last = current;
                }
            }

            data += current->size;
            datalen -= current->size;
        }

        if (i != header->subobjects || datalen != 0) {
            /* header data size doesn't match given subobject count */
            return ASF_ERROR_INVALID_VALUE;
        }

        ALOGV("%d subobjects read successfully\n", i);
    }

    tmp = asf_parse_header_validate(file->header);
    if (tmp < 0) {
        /* header read ok but doesn't validate correctly */
        return tmp;
    }

    ALOGV("header validated correctly\n");

    return header->size;
}