diff --git a/src/meta/ea_eaac.c b/src/meta/ea_eaac.c index 7fa6569e..436b9020 100644 --- a/src/meta/ea_eaac.c +++ b/src/meta/ea_eaac.c @@ -965,7 +965,7 @@ typedef struct { static segmented_layout_data* build_segmented_eaaudiocore_looping(STREAMFILE *sf_data, eaac_header *eaac); static layered_layout_data* build_layered_eaaudiocore(STREAMFILE *streamFile, eaac_header *eaac, off_t start_offset); static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead, STREAMFILE *streamData); -static size_t calculate_eaac_size(STREAMFILE *streamFile, uint32_t version, uint32_t num_samples, off_t start_offset); +static size_t calculate_eaac_size(STREAMFILE *streamFile, eaac_header *ea, uint32_t num_samples, off_t start_offset); /* EA newest header from RwAudioCore (RenderWare?) / EAAudioCore library (still generated by sx.exe). * Audio "assets" come in separate RAM headers (.SNR/SPH) and raw blocked streams (.SNS/SPS), @@ -1287,7 +1287,7 @@ fail: return NULL; } -static size_t calculate_eaac_size(STREAMFILE *streamFile, uint32_t version, uint32_t num_samples, off_t start_offset) { +static size_t calculate_eaac_size(STREAMFILE *streamFile, eaac_header *ea, uint32_t num_samples, off_t start_offset) { uint32_t samples_parsed, block_size, block_samples; uint8_t block_id; size_t stream_size, file_size; @@ -1301,12 +1301,18 @@ static size_t calculate_eaac_size(STREAMFILE *streamFile, uint32_t version, uint block_id = read_8bit(block_offset, streamFile); block_size = read_32bitBE(block_offset, streamFile) & 0x00FFFFFF; - if (version == EAAC_VERSION_V0) { + if (ea->version == EAAC_VERSION_V0) { if (block_id != EAAC_BLOCKID0_DATA && block_id != EAAC_BLOCKID0_END) goto fail; } else { - if (block_id != EAAC_BLOCKID1_DATA) + if (block_id != EAAC_BLOCKID1_DATA) { + if (block_id == EAAC_BLOCKID1_END && ea->codec == EAAC_CODEC_EATRAX) { + /* number of samples in block header is wrong for EATrax so stop when we reach end marker */ + return stream_size; + } + goto fail; + } } block_samples = read_32bitBE(block_offset + 0x04, streamFile); @@ -1336,7 +1342,7 @@ static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead switch (ea->type) { case EAAC_TYPE_RAM: /* both header and data in SNR */ - data_size = calculate_eaac_size(streamHead, ea->version, ea->num_samples, ea->stream_offset); + data_size = calculate_eaac_size(streamHead, ea, ea->num_samples, ea->stream_offset); if (data_size == 0) goto fail; new_streamFile = open_wrap_streamfile(streamHead); @@ -1349,7 +1355,7 @@ static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead break; case EAAC_TYPE_STREAM: /* header in SNR, data in SNS */ - data_size = calculate_eaac_size(streamData, ea->version, ea->num_samples, ea->stream_offset); + data_size = calculate_eaac_size(streamData, ea, ea->num_samples, ea->stream_offset); if (data_size == 0) goto fail; new_streamFile = open_wrap_streamfile(streamData); @@ -1363,7 +1369,7 @@ static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead case EAAC_TYPE_GIGASAMPLE: /* header and prefetched data in SNR, rest of data in SNS */ /* open prefetched data */ - data_size = calculate_eaac_size(streamHead, ea->version, ea->prefetch_samples, ea->prefetch_offset); + data_size = calculate_eaac_size(streamHead, ea, ea->prefetch_samples, ea->prefetch_offset); if (data_size == 0) goto fail; new_streamFile = open_wrap_streamfile(streamHead); @@ -1375,7 +1381,7 @@ static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead stream_segments[0] = new_streamFile; /* open main data */ - data_size = calculate_eaac_size(streamData, ea->version, ea->num_samples - ea->prefetch_samples, ea->stream_offset); + data_size = calculate_eaac_size(streamData, ea, ea->num_samples - ea->prefetch_samples, ea->stream_offset); if (data_size == 0) goto fail; new_streamFile = open_wrap_streamfile(streamData); @@ -1400,7 +1406,7 @@ static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead goto fail; } - data_size = calculate_eaac_size(streamHead, ea->version, ea->num_samples, ea->stream_offset); + data_size = calculate_eaac_size(streamHead, ea, ea->num_samples, ea->stream_offset); if (data_size == 0) goto fail; new_streamFile = open_wrap_streamfile(streamHead); diff --git a/src/meta/vag.c b/src/meta/vag.c index cbb2cc16..e231679b 100644 --- a/src/meta/vag.c +++ b/src/meta/vag.c @@ -199,13 +199,15 @@ VGMSTREAM * init_vgmstream_vag(STREAMFILE *streamFile) { interleave = 0x800; loop_flag = 0; } - else if (read_32bitBE(0x24, streamFile) == 0x56414778) { /* VAGx" */ + else if (read_32bitBE(0x24, streamFile) == 0x56414778) { /* "VAGx" */ /* Need for Speed: Hot Pursuit 2 (PS2) */ start_offset = 0x30; channel_count = read_32bitBE(0x2c, streamFile); channel_size = channel_size / channel_count; loop_flag = 0; + if (file_size % 0x10 != 0) goto fail; + /* detect interleave using end markers */ interleave = 0; @@ -214,7 +216,7 @@ VGMSTREAM * init_vgmstream_vag(STREAMFILE *streamFile) { off_t end_off = 0; uint8_t flag; - while (1) { + while (offset > start_offset) { offset -= 0x10; flag = read_8bit(offset + 0x01, streamFile); if (flag == 0x01) { @@ -225,9 +227,9 @@ VGMSTREAM * init_vgmstream_vag(STREAMFILE *streamFile) { break; } } - - if (offset == start_offset) goto fail; } + + if (!interleave) goto fail; } } else {