Merge branch 'parse-bad-wav'
Fix multiple problems with parsing untrusted input data in wxSound. Closes #11855.
This commit is contained in:
commit
0730236fa8
@ -651,35 +651,64 @@ bool wxSound::LoadWAV(const void* data_, size_t length, bool copyData)
|
||||
waveformat.uiBlockAlign = wxUINT16_SWAP_ON_BE(waveformat.uiBlockAlign);
|
||||
waveformat.uiBitsPerSample = wxUINT16_SWAP_ON_BE(waveformat.uiBitsPerSample);
|
||||
|
||||
// get the sound data size
|
||||
wxUint32 ul;
|
||||
memcpy(&ul, &data[FMT_INDEX + waveformat.uiSize + 12], 4);
|
||||
ul = wxUINT32_SWAP_ON_BE(ul);
|
||||
|
||||
if ( length < ul + FMT_INDEX + waveformat.uiSize + 16 )
|
||||
return false;
|
||||
|
||||
if (memcmp(data, "RIFF", 4) != 0)
|
||||
return false;
|
||||
if (memcmp(&data[WAVE_INDEX], "WAVE", 4) != 0)
|
||||
return false;
|
||||
if (memcmp(&data[FMT_INDEX], "fmt ", 4) != 0)
|
||||
return false;
|
||||
|
||||
// Check that the format chunk size is correct: it must be 16 for PCM,
|
||||
// which is the only format we handle.
|
||||
if (waveformat.uiSize != 16)
|
||||
return false;
|
||||
|
||||
if (memcmp(&data[FMT_INDEX + waveformat.uiSize + 8], "data", 4) != 0)
|
||||
return false;
|
||||
|
||||
if (waveformat.uiFormatTag != WAVE_FORMAT_PCM)
|
||||
return false;
|
||||
|
||||
if (waveformat.ulSamplesPerSec !=
|
||||
waveformat.ulAvgBytesPerSec / waveformat.uiBlockAlign)
|
||||
if (waveformat.ulAvgBytesPerSec !=
|
||||
waveformat.ulSamplesPerSec * waveformat.uiBlockAlign)
|
||||
return false;
|
||||
|
||||
// We divide by the sample size below to obtain the number of samples, so
|
||||
// it definitely can't be 0. Also take care to avoid integer overflow when
|
||||
// computing it.
|
||||
unsigned tmp = waveformat.uiChannels;
|
||||
if (tmp >= 0x10000)
|
||||
return false;
|
||||
|
||||
tmp *= waveformat.uiBitsPerSample;
|
||||
|
||||
wxUint32 const sampleSize = tmp / 8;
|
||||
if (!sampleSize)
|
||||
return false;
|
||||
|
||||
// get file size from header
|
||||
wxUint32 chunkSize;
|
||||
memcpy(&chunkSize, &data[4], 4);
|
||||
chunkSize = wxUINT32_SWAP_ON_BE(chunkSize);
|
||||
|
||||
// ensure file length is at least length in header
|
||||
if (chunkSize > length - 8)
|
||||
return false;
|
||||
|
||||
// get the sound data size
|
||||
wxUint32 ul;
|
||||
memcpy(&ul, &data[FMT_INDEX + waveformat.uiSize + 12], 4);
|
||||
ul = wxUINT32_SWAP_ON_BE(ul);
|
||||
|
||||
// ensure we actually have at least that much data in the input
|
||||
if (ul > length - FMT_INDEX - waveformat.uiSize - 16)
|
||||
return false;
|
||||
|
||||
m_data = new wxSoundData;
|
||||
m_data->m_channels = waveformat.uiChannels;
|
||||
m_data->m_samplingRate = waveformat.ulSamplesPerSec;
|
||||
m_data->m_bitsPerSample = waveformat.uiBitsPerSample;
|
||||
m_data->m_samples = ul / (m_data->m_channels * m_data->m_bitsPerSample / 8);
|
||||
m_data->m_samples = ul / sampleSize;
|
||||
m_data->m_dataBytes = ul;
|
||||
|
||||
if (copyData)
|
||||
|
Loading…
Reference in New Issue
Block a user