/** * 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; }
/** * 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; }