mirror of
https://github.com/ZDoom/raze-gles.git
synced 2024-12-25 11:10:47 +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,
|
void ( *mix )( uint32_t position, uint32_t rate,
|
||||||
const char *start, uint32_t length );
|
const char *start, uint32_t length );
|
||||||
|
|
||||||
|
const uint8_t *rawdataptr;
|
||||||
const char *NextBlock;
|
const char *NextBlock;
|
||||||
const char *LoopStart;
|
const char *LoopStart;
|
||||||
const char *LoopEnd;
|
const char *LoopEnd;
|
||||||
|
@ -129,6 +130,8 @@ typedef struct VoiceNode
|
||||||
uint32_t LoopSize;
|
uint32_t LoopSize;
|
||||||
uint32_t BlockLength;
|
uint32_t BlockLength;
|
||||||
|
|
||||||
|
int32_t ptrlength; // ptrlength-1 is the max permissible index for rawdataptr
|
||||||
|
|
||||||
uint32_t PitchScale;
|
uint32_t PitchScale;
|
||||||
uint32_t FixedPointBufferSize;
|
uint32_t FixedPointBufferSize;
|
||||||
|
|
||||||
|
|
|
@ -480,7 +480,7 @@ static void MV_ServiceVoc(void)
|
||||||
|
|
||||||
static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
||||||
{
|
{
|
||||||
uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
int32_t blocktype;
|
int32_t blocktype;
|
||||||
int32_t lastblocktype;
|
int32_t lastblocktype;
|
||||||
uint32_t blocklength;
|
uint32_t blocklength;
|
||||||
|
@ -524,13 +524,27 @@ static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
blocktype = (int32_t)*ptr;
|
// terminator is not mandatory according to
|
||||||
blocklength = LITTLE32(*(uint32_t *)(ptr + 1)) & 0x00ffffff;
|
// 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;
|
ptr += 4;
|
||||||
|
|
||||||
switch (blocktype)
|
switch (blocktype)
|
||||||
{
|
{
|
||||||
case 0 :
|
case 0 :
|
||||||
|
end_of_data:
|
||||||
// End of data
|
// End of data
|
||||||
if ((voice->LoopStart == NULL) ||
|
if ((voice->LoopStart == NULL) ||
|
||||||
((intptr_t) voice->LoopStart >= ((intptr_t) ptr - 4)))
|
((intptr_t) voice->LoopStart >= ((intptr_t) ptr - 4)))
|
||||||
|
@ -571,6 +585,9 @@ static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
||||||
{
|
{
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
}
|
}
|
||||||
|
if (ptr - voice->rawdataptr >= voice->ptrlength)
|
||||||
|
goto end_of_data;
|
||||||
|
|
||||||
voicemode = 0;
|
voicemode = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -671,6 +688,13 @@ static playbackstatus MV_GetNextVOCBlock(VoiceNode *voice)
|
||||||
{
|
{
|
||||||
ptr += blocklength;
|
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;
|
break;
|
||||||
|
|
||||||
default :
|
default :
|
||||||
|
@ -2043,7 +2067,6 @@ int32_t MV_PlayLoopedWAV
|
||||||
VoiceNode *voice;
|
VoiceNode *voice;
|
||||||
int32_t length;
|
int32_t length;
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(ptrlength);
|
|
||||||
UNREFERENCED_PARAMETER(loopend);
|
UNREFERENCED_PARAMETER(loopend);
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
|
@ -2126,6 +2149,8 @@ int32_t MV_PlayLoopedWAV
|
||||||
length /= 2;
|
length /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
voice->rawdataptr = (uint8_t *)ptr;
|
||||||
|
voice->ptrlength = ptrlength;
|
||||||
voice->Playing = TRUE;
|
voice->Playing = TRUE;
|
||||||
voice->Paused = FALSE;
|
voice->Paused = FALSE;
|
||||||
voice->DemandFeed = NULL;
|
voice->DemandFeed = NULL;
|
||||||
|
@ -2258,8 +2283,6 @@ int32_t MV_PlayLoopedVOC
|
||||||
VoiceNode *voice;
|
VoiceNode *voice;
|
||||||
int32_t status;
|
int32_t status;
|
||||||
|
|
||||||
UNREFERENCED_PARAMETER(ptrlength);
|
|
||||||
|
|
||||||
if (!MV_Installed)
|
if (!MV_Installed)
|
||||||
{
|
{
|
||||||
MV_SetErrorCode(MV_NotInstalled);
|
MV_SetErrorCode(MV_NotInstalled);
|
||||||
|
@ -2282,6 +2305,8 @@ int32_t MV_PlayLoopedVOC
|
||||||
return(MV_Error);
|
return(MV_Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
voice->rawdataptr = (uint8_t *)ptr;
|
||||||
|
voice->ptrlength = ptrlength;
|
||||||
voice->Playing = TRUE;
|
voice->Playing = TRUE;
|
||||||
voice->Paused = FALSE;
|
voice->Paused = FALSE;
|
||||||
voice->wavetype = VOC;
|
voice->wavetype = VOC;
|
||||||
|
|
Loading…
Reference in a new issue