mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-11-11 07:11:39 +00:00
Clean up VOC in-memory block type parsing.
- Maintain a position relative to the start of the data. VOC doesn't mandate an EOF marker (blocktype 0). If we go over the end, fake that marker, so as to restart a looping sound or stop a one-shot one. This fixes an uninitialized mem access with the corrupt SNAKRM.VOC. - When encountering the EOF marker, don't read the 3 bytes of block size, since they may not be there. - Read blocksize by ORing and shifting the 3 bytes, not with *(int32_t *)... git-svn-id: https://svn.eduke32.com/eduke32@2346 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
parent
17ba2664f9
commit
ebbf4d79ce
2 changed files with 34 additions and 6 deletions
|
@ -122,6 +122,7 @@ typedef struct VoiceNode
|
|||
void ( *mix )( uint32_t position, uint32_t rate,
|
||||
const char *start, uint32_t length );
|
||||
|
||||
const uint8_t *rawdataptr;
|
||||
const char *NextBlock;
|
||||
const char *LoopStart;
|
||||
const char *LoopEnd;
|
||||
|
@ -129,6 +130,8 @@ typedef struct VoiceNode
|
|||
uint32_t LoopSize;
|
||||
uint32_t BlockLength;
|
||||
|
||||
int32_t ptrlength; // ptrlength-1 is the max permissible index for rawdataptr
|
||||
|
||||
uint32_t PitchScale;
|
||||
uint32_t FixedPointBufferSize;
|
||||
|
||||
|
|
|
@ -480,7 +480,7 @@ static void MV_ServiceVoc(void)
|
|||
|
||||
static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
const uint8_t *ptr;
|
||||
int32_t blocktype;
|
||||
int32_t lastblocktype;
|
||||
uint32_t blocklength;
|
||||
|
@ -524,13 +524,27 @@ static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
|||
break;
|
||||
}
|
||||
|
||||
blocktype = (int32_t)*ptr;
|
||||
blocklength = LITTLE32(*(uint32_t *)(ptr + 1)) & 0x00ffffff;
|
||||
// terminator is not mandatory according to
|
||||
// http://wiki.multimedia.cx/index.php?title=Creative_Voice
|
||||
|
||||
if (ptr - voice->rawdataptr >= voice->ptrlength)
|
||||
blocktype = 0; // fake a terminator
|
||||
else
|
||||
blocktype = *ptr;
|
||||
|
||||
if (blocktype != 0)
|
||||
blocklength = ptr[1]|(ptr[2]<<8)|(ptr[3]<<16);
|
||||
else
|
||||
blocklength = 0;
|
||||
// would need one byte pad at end of alloc'd region:
|
||||
// blocklength = LITTLE32(*(uint32_t *)(ptr + 1)) & 0x00ffffff;
|
||||
|
||||
ptr += 4;
|
||||
|
||||
switch (blocktype)
|
||||
{
|
||||
case 0 :
|
||||
end_of_data:
|
||||
// End of data
|
||||
if ((voice->LoopStart == NULL) ||
|
||||
((intptr_t) voice->LoopStart >= ((intptr_t) ptr - 4)))
|
||||
|
@ -571,6 +585,9 @@ static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
|||
{
|
||||
done = TRUE;
|
||||
}
|
||||
if (ptr - voice->rawdataptr >= voice->ptrlength)
|
||||
goto end_of_data;
|
||||
|
||||
voicemode = 0;
|
||||
break;
|
||||
|
||||
|
@ -671,6 +688,13 @@ static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
|||
{
|
||||
ptr += blocklength;
|
||||
}
|
||||
|
||||
// CAUTION:
|
||||
// SNAKRM.VOC is corrupt! blocklength gets us beyond the
|
||||
// end of the file.
|
||||
if (ptr - voice->rawdataptr >= voice->ptrlength)
|
||||
goto end_of_data;
|
||||
|
||||
break;
|
||||
|
||||
default :
|
||||
|
@ -2043,7 +2067,6 @@ int32_t MV_PlayLoopedWAV
|
|||
VoiceNode *voice;
|
||||
int32_t length;
|
||||
|
||||
UNREFERENCED_PARAMETER(ptrlength);
|
||||
UNREFERENCED_PARAMETER(loopend);
|
||||
|
||||
if (!MV_Installed)
|
||||
|
@ -2126,6 +2149,8 @@ int32_t MV_PlayLoopedWAV
|
|||
length /= 2;
|
||||
}
|
||||
|
||||
voice->rawdataptr = (uint8_t *)ptr;
|
||||
voice->ptrlength = ptrlength;
|
||||
voice->Playing = TRUE;
|
||||
voice->Paused = FALSE;
|
||||
voice->DemandFeed = NULL;
|
||||
|
@ -2258,8 +2283,6 @@ int32_t MV_PlayLoopedVOC
|
|||
VoiceNode *voice;
|
||||
int32_t status;
|
||||
|
||||
UNREFERENCED_PARAMETER(ptrlength);
|
||||
|
||||
if (!MV_Installed)
|
||||
{
|
||||
MV_SetErrorCode(MV_NotInstalled);
|
||||
|
@ -2282,6 +2305,8 @@ int32_t MV_PlayLoopedVOC
|
|||
return(MV_Error);
|
||||
}
|
||||
|
||||
voice->rawdataptr = (uint8_t *)ptr;
|
||||
voice->ptrlength = ptrlength;
|
||||
voice->Playing = TRUE;
|
||||
voice->Paused = FALSE;
|
||||
voice->wavetype = VOC;
|
||||
|
|
Loading…
Reference in a new issue