]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/sound.cpp
fix memory leak while testing for correct Clone() implementation (closes #10304)
[wxWidgets.git] / src / unix / sound.cpp
index 6afa44f146d97c5336f01c5b38dbc04c130659fa..0afab5a47be20af4ea990f0dc8ad1a8f6ab5179c 100644 (file)
@@ -13,7 +13,7 @@
 #include "wx/wxprec.h"
 
 #if defined(__BORLANDC__)
 #include "wx/wxprec.h"
 
 #if defined(__BORLANDC__)
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #if wxUSE_SOUND
 #endif
 
 #if wxUSE_SOUND
     #include "wx/event.h"
     #include "wx/intl.h"
     #include "wx/log.h"
     #include "wx/event.h"
     #include "wx/intl.h"
     #include "wx/log.h"
+    #include "wx/module.h"
 #endif
 
 #include "wx/thread.h"
 #include "wx/file.h"
 #endif
 
 #include "wx/thread.h"
 #include "wx/file.h"
-#include "wx/module.h"
 #include "wx/sound.h"
 #include "wx/dynlib.h"
 
 #include "wx/sound.h"
 #include "wx/dynlib.h"
 
@@ -296,7 +296,7 @@ class wxSoundSyncOnlyAdaptor : public wxSoundBackend
 public:
     wxSoundSyncOnlyAdaptor(wxSoundBackend *backend)
         : m_backend(backend), m_playing(false) {}
 public:
     wxSoundSyncOnlyAdaptor(wxSoundBackend *backend)
         : m_backend(backend), m_playing(false) {}
-    ~wxSoundSyncOnlyAdaptor()
+    virtual ~wxSoundSyncOnlyAdaptor()
     {
         delete m_backend;
     }
     {
         delete m_backend;
     }
@@ -467,12 +467,14 @@ bool wxSound::Create(const wxString& fileName,
     wxUint8 *data = new wxUint8[len];
     if ( fileWave.Read(data, len) != lenOrig )
     {
     wxUint8 *data = new wxUint8[len];
     if ( fileWave.Read(data, len) != lenOrig )
     {
+        delete [] data;
         wxLogError(_("Couldn't load sound data from '%s'."), fileName.c_str());
         return false;
     }
 
     if (!LoadWAV(data, len, false))
     {
         wxLogError(_("Couldn't load sound data from '%s'."), fileName.c_str());
         return false;
     }
 
     if (!LoadWAV(data, len, false))
     {
+        delete [] data;
         wxLogError(_("Sound file '%s' is in unsupported format."),
                    fileName.c_str());
         return false;
         wxLogError(_("Sound file '%s' is in unsupported format."),
                    fileName.c_str());
         return false;
@@ -624,12 +626,30 @@ typedef struct
 
 bool wxSound::LoadWAV(const wxUint8 *data, size_t length, bool copyData)
 {
 
 bool wxSound::LoadWAV(const wxUint8 *data, size_t length, bool copyData)
 {
-    WAVEFORMAT waveformat;
-    wxUint32 ul;
-
-    if (length < 32 + sizeof(WAVEFORMAT))
+    // the simplest wave file header consists of 44 bytes:
+    //
+    //      0   "RIFF"
+    //      4   file size - 8
+    //      8   "WAVE"
+    //
+    //      12  "fmt "
+    //      16  chunk size                  |
+    //      20  format tag                  |
+    //      22  number of channels          |
+    //      24  sample rate                 | WAVEFORMAT
+    //      28  average bytes per second    |
+    //      32  bytes per frame             |
+    //      34  bits per sample             |
+    //
+    //      36  "data"
+    //      40  number of data bytes
+    //      44  (wave signal) data
+    //
+    // so check that we have at least as much
+    if ( length < 44 )
         return false;
 
         return false;
 
+    WAVEFORMAT waveformat;
     memcpy(&waveformat, &data[FMT_INDEX + 4], sizeof(WAVEFORMAT));
     waveformat.uiSize = wxUINT32_SWAP_ON_BE(waveformat.uiSize);
     waveformat.uiFormatTag = wxUINT16_SWAP_ON_BE(waveformat.uiFormatTag);
     memcpy(&waveformat, &data[FMT_INDEX + 4], sizeof(WAVEFORMAT));
     waveformat.uiSize = wxUINT32_SWAP_ON_BE(waveformat.uiSize);
     waveformat.uiFormatTag = wxUINT16_SWAP_ON_BE(waveformat.uiFormatTag);
@@ -639,6 +659,14 @@ bool wxSound::LoadWAV(const wxUint8 *data, size_t length, bool copyData)
     waveformat.uiBlockAlign = wxUINT16_SWAP_ON_BE(waveformat.uiBlockAlign);
     waveformat.uiBitsPerSample = wxUINT16_SWAP_ON_BE(waveformat.uiBitsPerSample);
 
     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)
     if (memcmp(data, "RIFF", 4) != 0)
         return false;
     if (memcmp(&data[WAVE_INDEX], "WAVE", 4) != 0)
@@ -647,12 +675,6 @@ bool wxSound::LoadWAV(const wxUint8 *data, size_t length, bool copyData)
         return false;
     if (memcmp(&data[FMT_INDEX + waveformat.uiSize + 8], "data", 4) != 0)
         return false;
         return false;
     if (memcmp(&data[FMT_INDEX + waveformat.uiSize + 8], "data", 4) != 0)
         return false;
-    memcpy(&ul,&data[FMT_INDEX + waveformat.uiSize + 12], 4);
-    ul = wxUINT32_SWAP_ON_BE(ul);
-
-    //WAS: if (ul + FMT_INDEX + waveformat.uiSize + 16 != length)
-    if (ul + FMT_INDEX + waveformat.uiSize + 16 > length)
-        return false;
 
     if (waveformat.uiFormatTag != WAVE_FORMAT_PCM)
         return false;
 
     if (waveformat.uiFormatTag != WAVE_FORMAT_PCM)
         return false;