浏览代码

File refactoring.
Updated to latest stb_vorbis.
Removed soloud thread registering.

woollybah 5 年之前
父节点
当前提交
b64a1b2826

+ 66 - 0
soloud.mod/file.bmx

@@ -0,0 +1,66 @@
+' Copyright (c) 2016-2019 Bruce A Henderson
+'
+' This software is provided 'as-is', without any express or implied
+' warranty. In no event will the authors be held liable for any damages
+' arising from the use of this software.
+'
+' Permission is granted to anyone to use this software for any purpose,
+' including commercial applications, and to alter it and redistribute it
+' freely, subject to the following restrictions:
+'
+'    1. The origin of this software must not be misrepresented; you must not
+'    claim that you wrote the original software. If you use this software
+'    in a product, an acknowledgment in the product documentation would be
+'    appreciated but is not required.
+'
+'    2. Altered source versions must be plainly marked as such, and must not be
+'    misrepresented as being the original software.
+'
+'    3. This notice may not be removed or altered from any source
+'    distribution.
+'
+SuperStrict
+
+Import "common.bmx"
+
+
+Type TStreamFile
+
+	Field filePtr:Byte Ptr
+	Field stream:TStream
+	
+	Method Create:TStreamFile(stream:TStream)
+		filePtr = bmx_soloud_streamfile_new(Self)
+		Self.stream = stream
+		stream.Seek(0)
+		Return Self
+	End Method
+	
+	Function _eof:Int(sf:TStreamFile) { nomangle }
+		Return sf.stream.Eof()
+	End Function
+
+	Function _seek(sf:TStreamFile, offset:Int) { nomangle }
+		sf.stream.Seek(offset)
+	End Function
+	
+	Function _length:Int(sf:TStreamFile) { nomangle }
+		Return sf.stream.Size()
+	End Function
+	
+	Function _pos:Int(sf:TStreamFile) { nomangle }
+		Return sf.stream.Pos()
+	End Function
+	
+	Function _read:Int(sf:TStreamFile, dst:Byte Ptr, size:Int) { nomangle }
+		Return sf.stream.Read(dst, size)
+	End Function
+
+	Method Free()
+		If filePtr Then
+			bmx_soloud_streamfile_free(filePtr)
+			filePtr = Null
+		End If
+	End Method
+
+End Type

+ 10 - 10
soloud.mod/glue.cpp

@@ -5,11 +5,11 @@ extern "C" {
 
 
 	#include "brl.mod/blitz.mod/blitz.h"
 	#include "brl.mod/blitz.mod/blitz.h"
 
 
-	int audio_soloud_TStreamFile__eof(BBObject * handle);
-	void audio_soloud_TStreamFile__seek(BBObject * handle, int offset);
-	int audio_soloud_TStreamFile__length(BBObject * handle);
-	int audio_soloud_TStreamFile__pos(BBObject * handle);
-	int audio_soloud_TStreamFile__read(BBObject * handle, unsigned char * dst, int size);
+	int audio_soloud_file_TStreamFile__eof(BBObject * handle);
+	void audio_soloud_file_TStreamFile__seek(BBObject * handle, int offset);
+	int audio_soloud_file_TStreamFile__length(BBObject * handle);
+	int audio_soloud_file_TStreamFile__pos(BBObject * handle);
+	int audio_soloud_file_TStreamFile__read(BBObject * handle, unsigned char * dst, int size);
 
 
 	SoLoud::File * bmx_soloud_streamfile_new(BBObject * handle);
 	SoLoud::File * bmx_soloud_streamfile_new(BBObject * handle);
 	void bmx_soloud_streamfile_free(SoLoud::File * file);
 	void bmx_soloud_streamfile_free(SoLoud::File * file);
@@ -31,23 +31,23 @@ public:
 	}
 	}
 	
 	
 	virtual int eof() {
 	virtual int eof() {
-		return audio_soloud_TStreamFile__eof(maxHandle);
+		return audio_soloud_file_TStreamFile__eof(maxHandle);
 	}
 	}
 	
 	
 	virtual unsigned int read(unsigned char *aDst, unsigned int aBytes) {
 	virtual unsigned int read(unsigned char *aDst, unsigned int aBytes) {
-		return audio_soloud_TStreamFile__read(maxHandle, aDst, aBytes);
+		return audio_soloud_file_TStreamFile__read(maxHandle, aDst, aBytes);
 	}
 	}
 	
 	
 	virtual unsigned int length() {
 	virtual unsigned int length() {
-		return audio_soloud_TStreamFile__length(maxHandle);
+		return audio_soloud_file_TStreamFile__length(maxHandle);
 	}
 	}
 	
 	
 	virtual void seek(int aOffset) {
 	virtual void seek(int aOffset) {
-		audio_soloud_TStreamFile__seek(maxHandle, aOffset);
+		audio_soloud_file_TStreamFile__seek(maxHandle, aOffset);
 	}
 	}
 	
 	
 	virtual unsigned int pos() {
 	virtual unsigned int pos() {
-		return audio_soloud_TStreamFile__pos(maxHandle);
+		return audio_soloud_file_TStreamFile__pos(maxHandle);
 	}
 	}
 	
 	
 private:
 private:

+ 1 - 42
soloud.mod/soloud.bmx

@@ -45,6 +45,7 @@ ModuleInfo "CC_OPTS: -msse3"
 ?
 ?
 ModuleInfo "CC_OPTS: -DWITH_SDL2_STATIC"
 ModuleInfo "CC_OPTS: -DWITH_SDL2_STATIC"
 
 
+Import "file.bmx"
 Import "common.bmx"
 Import "common.bmx"
 
 
 
 
@@ -1407,45 +1408,3 @@ End Type
 Type TSLFilter
 Type TSLFilter
 End Type
 End Type
 
 
-' stream file must be manually freed.
-Type TStreamFile
-
-	Field filePtr:Byte Ptr
-	Field stream:TStream
-	
-	Method Create:TStreamFile(stream:TStream)
-		filePtr = bmx_soloud_streamfile_new(Self)
-		Self.stream = stream
-		stream.Seek(0)
-		Return Self
-	End Method
-	
-	Function _eof:Int(sf:TStreamFile) { nomangle }
-		Return sf.stream.Eof()
-	End Function
-
-	Function _seek(sf:TStreamFile, offset:Int) { nomangle }
-		sf.stream.Seek(offset)
-	End Function
-	
-	Function _length:Int(sf:TStreamFile) { nomangle }
-		Return sf.stream.Size()
-	End Function
-	
-	Function _pos:Int(sf:TStreamFile) { nomangle }
-		Return sf.stream.Pos()
-	End Function
-	
-	Function _read:Int(sf:TStreamFile, dst:Byte Ptr, size:Int) { nomangle }
-		Return sf.stream.Read(dst, size)
-	End Function
-
-	Method Free()
-		If filePtr Then
-			bmx_soloud_streamfile_free(filePtr)
-			filePtr = Null
-		End If
-	End Method
-
-End Type
-

+ 55 - 15
soloud.mod/soloud/src/audiosource/wav/stb_vorbis.c

@@ -1,4 +1,4 @@
-// Ogg Vorbis audio decoder - v1.14 - public domain
+// Ogg Vorbis audio decoder - v1.17 - public domain
 // http://nothings.org/stb_vorbis/
 // http://nothings.org/stb_vorbis/
 //
 //
 // Original version written by Sean Barrett in 2007.
 // Original version written by Sean Barrett in 2007.
@@ -30,9 +30,12 @@
 //    Tom Beaumont       Ingo Leitgeb        Nicolas Guillemot
 //    Tom Beaumont       Ingo Leitgeb        Nicolas Guillemot
 //    Phillip Bennefall  Rohit               Thiago Goulart
 //    Phillip Bennefall  Rohit               Thiago Goulart
 //    manxorist@github   saga musix          github:infatum
 //    manxorist@github   saga musix          github:infatum
-//    Timur Gagiev
+//    Timur Gagiev       Maxwell Koo
 //
 //
 // Partial history:
 // Partial history:
+//    1.17    - 2019-07-08 - fix CVE-2019-13217..CVE-2019-13223 (by ForAllSecure)
+//    1.16    - 2019-03-04 - fix warnings
+//    1.15    - 2019-02-07 - explicit failure if Ogg Skeleton data is found
 //    1.14    - 2018-02-11 - delete bogus dealloca usage
 //    1.14    - 2018-02-11 - delete bogus dealloca usage
 //    1.13    - 2018-01-29 - fix truncation of last frame (hopefully)
 //    1.13    - 2018-01-29 - fix truncation of last frame (hopefully)
 //    1.12    - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
 //    1.12    - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
@@ -255,7 +258,7 @@ extern stb_vorbis * stb_vorbis_open_file(FILE *f, int close_handle_on_close,
 // create an ogg vorbis decoder from an open FILE *, looking for a stream at
 // create an ogg vorbis decoder from an open FILE *, looking for a stream at
 // the _current_ seek point (ftell). on failure, returns NULL and sets *error.
 // the _current_ seek point (ftell). on failure, returns NULL and sets *error.
 // note that stb_vorbis must "own" this stream; if you seek it in between
 // note that stb_vorbis must "own" this stream; if you seek it in between
-// calls to stb_vorbis, it will become confused. Morever, if you attempt to
+// calls to stb_vorbis, it will become confused. Moreover, if you attempt to
 // perform stb_vorbis_seek_*() operations on this file, it will assume it
 // perform stb_vorbis_seek_*() operations on this file, it will assume it
 // owns the _entire_ rest of the file after the start point. Use the next
 // owns the _entire_ rest of the file after the start point. Use the next
 // function, stb_vorbis_open_file_section(), to limit it.
 // function, stb_vorbis_open_file_section(), to limit it.
@@ -376,7 +379,8 @@ enum STBVorbisError
    VORBIS_invalid_first_page,
    VORBIS_invalid_first_page,
    VORBIS_bad_packet_type,
    VORBIS_bad_packet_type,
    VORBIS_cant_find_last_page,
    VORBIS_cant_find_last_page,
-   VORBIS_seek_failed
+   VORBIS_seek_failed,
+   VORBIS_ogg_skeleton_not_supported
 };
 };
 
 
 
 
@@ -1075,7 +1079,7 @@ static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values)
       assert(z >= 0 && z < 32);
       assert(z >= 0 && z < 32);
       available[z] = 0;
       available[z] = 0;
       add_entry(c, bit_reverse(res), i, m++, len[i], values);
       add_entry(c, bit_reverse(res), i, m++, len[i], values);
-      // propogate availability up the tree
+      // propagate availability up the tree
       if (z != len[i]) {
       if (z != len[i]) {
          assert(len[i] >= 0 && len[i] < 32);
          assert(len[i] >= 0 && len[i] < 32);
          for (y=len[i]; y > z; --y) {
          for (y=len[i]; y > z; --y) {
@@ -1201,8 +1205,10 @@ static int lookup1_values(int entries, int dim)
    int r = (int) floor(exp((float) log((float) entries) / dim));
    int r = (int) floor(exp((float) log((float) entries) / dim));
    if ((int) floor(pow((float) r+1, dim)) <= entries)   // (int) cast for MinGW warning;
    if ((int) floor(pow((float) r+1, dim)) <= entries)   // (int) cast for MinGW warning;
       ++r;                                              // floor() to avoid _ftol() when non-CRT
       ++r;                                              // floor() to avoid _ftol() when non-CRT
-   assert(pow((float) r+1, dim) > entries);
-   assert((int) floor(pow((float) r, dim)) <= entries); // (int),floor() as above
+   if (pow((float) r+1, dim) <= entries)
+      return -1;
+   if ((int) floor(pow((float) r, dim)) > entries)
+      return -1;
    return r;
    return r;
 }
 }
 
 
@@ -2012,7 +2018,7 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y
    ady -= abs(base) * adx;
    ady -= abs(base) * adx;
    if (x1 > n) x1 = n;
    if (x1 > n) x1 = n;
    if (x < x1) {
    if (x < x1) {
-      LINE_OP(output[x], inverse_db_table[y]);
+      LINE_OP(output[x], inverse_db_table[y&255]);
       for (++x; x < x1; ++x) {
       for (++x; x < x1; ++x) {
          err += ady;
          err += ady;
          if (err >= adx) {
          if (err >= adx) {
@@ -2020,7 +2026,7 @@ static __forceinline void draw_line(float *output, int x0, int y0, int x1, int y
             y += sy;
             y += sy;
          } else
          } else
             y += base;
             y += base;
-         LINE_OP(output[x], inverse_db_table[y]);
+         LINE_OP(output[x], inverse_db_table[y&255]);
       }
       }
    }
    }
 }
 }
@@ -2639,7 +2645,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype)
    // once I combined the passes.
    // once I combined the passes.
 
 
    // so there's a missing 'times 2' here (for adding X to itself).
    // so there's a missing 'times 2' here (for adding X to itself).
-   // this propogates through linearly to the end, where the numbers
+   // this propagates through linearly to the end, where the numbers
    // are 1/2 too small, and need to be compensated for.
    // are 1/2 too small, and need to be compensated for.
 
 
    {
    {
@@ -3047,7 +3053,6 @@ static float *get_window(vorb *f, int len)
    len <<= 1;
    len <<= 1;
    if (len == f->blocksize_0) return f->window[0];
    if (len == f->blocksize_0) return f->window[0];
    if (len == f->blocksize_1) return f->window[1];
    if (len == f->blocksize_1) return f->window[1];
-   assert(0);
    return NULL;
    return NULL;
 }
 }
 
 
@@ -3453,6 +3458,7 @@ static int vorbis_finish_frame(stb_vorbis *f, int len, int left, int right)
    if (f->previous_length) {
    if (f->previous_length) {
       int i,j, n = f->previous_length;
       int i,j, n = f->previous_length;
       float *w = get_window(f, n);
       float *w = get_window(f, n);
+      if (w == NULL) return 0;
       for (i=0; i < f->channels; ++i) {
       for (i=0; i < f->channels; ++i) {
          for (j=0; j < n; ++j)
          for (j=0; j < n; ++j)
             f->channel_buffers[i][left+j] =
             f->channel_buffers[i][left+j] =
@@ -3580,7 +3586,22 @@ static int start_decoder(vorb *f)
    if (f->page_flag & PAGEFLAG_continued_packet)    return error(f, VORBIS_invalid_first_page);
    if (f->page_flag & PAGEFLAG_continued_packet)    return error(f, VORBIS_invalid_first_page);
    // check for expected packet length
    // check for expected packet length
    if (f->segment_count != 1)                       return error(f, VORBIS_invalid_first_page);
    if (f->segment_count != 1)                       return error(f, VORBIS_invalid_first_page);
-   if (f->segments[0] != 30)                        return error(f, VORBIS_invalid_first_page);
+   if (f->segments[0] != 30) {
+      // check for the Ogg skeleton fishead identifying header to refine our error
+      if (f->segments[0] == 64 &&
+          getn(f, header, 6) &&
+          header[0] == 'f' &&
+          header[1] == 'i' &&
+          header[2] == 's' &&
+          header[3] == 'h' &&
+          header[4] == 'e' &&
+          header[5] == 'a' &&
+          get8(f)   == 'd' &&
+          get8(f)   == '\0')                        return error(f, VORBIS_ogg_skeleton_not_supported);
+      else
+                                                    return error(f, VORBIS_invalid_first_page);
+   }
+
    // read packet
    // read packet
    // check packet header
    // check packet header
    if (get8(f) != VORBIS_packet_id)                 return error(f, VORBIS_invalid_first_page);
    if (get8(f) != VORBIS_packet_id)                 return error(f, VORBIS_invalid_first_page);
@@ -3679,6 +3700,7 @@ static int start_decoder(vorb *f)
          while (current_entry < c->entries) {
          while (current_entry < c->entries) {
             int limit = c->entries - current_entry;
             int limit = c->entries - current_entry;
             int n = get_bits(f, ilog(limit));
             int n = get_bits(f, ilog(limit));
+            if (current_length >= 32) return error(f, VORBIS_invalid_setup);
             if (current_entry + n > (int) c->entries) { return error(f, VORBIS_invalid_setup); }
             if (current_entry + n > (int) c->entries) { return error(f, VORBIS_invalid_setup); }
             memset(lengths + current_entry, current_length, n);
             memset(lengths + current_entry, current_length, n);
             current_entry += n;
             current_entry += n;
@@ -3782,7 +3804,9 @@ static int start_decoder(vorb *f)
          c->value_bits = get_bits(f, 4)+1;
          c->value_bits = get_bits(f, 4)+1;
          c->sequence_p = get_bits(f,1);
          c->sequence_p = get_bits(f,1);
          if (c->lookup_type == 1) {
          if (c->lookup_type == 1) {
-            c->lookup_values = lookup1_values(c->entries, c->dimensions);
+            int values = lookup1_values(c->entries, c->dimensions);
+            if (values < 0) return error(f, VORBIS_invalid_setup);
+            c->lookup_values = (uint32) values;
          } else {
          } else {
             c->lookup_values = c->entries * c->dimensions;
             c->lookup_values = c->entries * c->dimensions;
          }
          }
@@ -3918,6 +3942,9 @@ static int start_decoder(vorb *f)
             p[j].id = j;
             p[j].id = j;
          }
          }
          qsort(p, g->values, sizeof(p[0]), point_compare);
          qsort(p, g->values, sizeof(p[0]), point_compare);
+         for (j=0; j < g->values-1; ++j)
+            if (p[j].x == p[j+1].x)
+               return error(f, VORBIS_invalid_setup);
          for (j=0; j < g->values; ++j)
          for (j=0; j < g->values; ++j)
             g->sorted_order[j] = (uint8) p[j].id;
             g->sorted_order[j] = (uint8) p[j].id;
          // precompute the neighbors
          // precompute the neighbors
@@ -4004,6 +4031,7 @@ static int start_decoder(vorb *f)
          max_submaps = m->submaps;
          max_submaps = m->submaps;
       if (get_bits(f,1)) {
       if (get_bits(f,1)) {
          m->coupling_steps = get_bits(f,8)+1;
          m->coupling_steps = get_bits(f,8)+1;
+         if (m->coupling_steps > f->channels) return error(f, VORBIS_invalid_setup);
          for (k=0; k < m->coupling_steps; ++k) {
          for (k=0; k < m->coupling_steps; ++k) {
             m->chan[k].magnitude = get_bits(f, ilog(f->channels-1));
             m->chan[k].magnitude = get_bits(f, ilog(f->channels-1));
             m->chan[k].angle = get_bits(f, ilog(f->channels-1));
             m->chan[k].angle = get_bits(f, ilog(f->channels-1));
@@ -4568,7 +4596,7 @@ static int get_seek_page_info(stb_vorbis *f, ProbedPage *z)
    return 1;
    return 1;
 }
 }
 
 
-// rarely used function to seek back to the preceeding page while finding the
+// rarely used function to seek back to the preceding page while finding the
 // start of a packet
 // start of a packet
 static int go_to_page_before(stb_vorbis *f, unsigned int limit_offset)
 static int go_to_page_before(stb_vorbis *f, unsigned int limit_offset)
 {
 {
@@ -4975,7 +5003,13 @@ stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, con
 
 
 stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc)
 stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc)
 {
 {
-   FILE *f = fopen(filename, "rb");
+   FILE *f;
+#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__)
+   if (0 != fopen_s(&f, filename, "rb"))
+      f = NULL;
+#else
+   f = fopen(filename, "rb");
+#endif
    if (f) 
    if (f) 
       return stb_vorbis_open_file(f, TRUE, error, alloc);
       return stb_vorbis_open_file(f, TRUE, error, alloc);
    if (error) *error = VORBIS_file_open_failure;
    if (error) *error = VORBIS_file_open_failure;
@@ -5364,6 +5398,12 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
 #endif // STB_VORBIS_NO_PULLDATA_API
 #endif // STB_VORBIS_NO_PULLDATA_API
 
 
 /* Version history
 /* Version history
+    1.17    - 2019-07-08 - fix CVE-2019-13217, -13218, -13219, -13220, -13221, -13222, -13223
+                           found with Mayhem by ForAllSecure
+    1.16    - 2019-03-04 - fix warnings
+    1.15    - 2019-02-07 - explicit failure if Ogg Skeleton data is found
+    1.14    - 2018-02-11 - delete bogus dealloca usage
+    1.13    - 2018-01-29 - fix truncation of last frame (hopefully)
     1.12    - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
     1.12    - 2017-11-21 - limit residue begin/end to blocksize/2 to avoid large temp allocs in bad/corrupt files
     1.11    - 2017-07-23 - fix MinGW compilation 
     1.11    - 2017-07-23 - fix MinGW compilation 
     1.10    - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory
     1.10    - 2017-03-03 - more robust seeking; fix negative ilog(); clear error in open_memory

+ 0 - 5
soloud.mod/soloud/src/core/soloud_thread.cpp

@@ -32,8 +32,6 @@ freely, subject to the following restrictions:
 #include "soloud.h"
 #include "soloud.h"
 #include "soloud_thread.h"
 #include "soloud_thread.h"
 
 
-#include "brl.mod/blitz.mod/blitz.h"
-
 namespace SoLoud
 namespace SoLoud
 {
 {
 	namespace Thread
 	namespace Thread
@@ -42,7 +40,6 @@ namespace SoLoud
         struct ThreadHandleData
         struct ThreadHandleData
         {
         {
             HANDLE thread;
             HANDLE thread;
-			BBThread * bbThread;
         };
         };
 
 
 		void * createMutex()
 		void * createMutex()
@@ -104,7 +101,6 @@ namespace SoLoud
             }
             }
             ThreadHandleData *threadHandle = new ThreadHandleData;
             ThreadHandleData *threadHandle = new ThreadHandleData;
             threadHandle->thread = h;
             threadHandle->thread = h;
-			threadHandle->bbThread = bbThreadRegister( id );
             return threadHandle;
             return threadHandle;
 		}
 		}
 
 
@@ -120,7 +116,6 @@ namespace SoLoud
 
 
         void release(ThreadHandle aThreadHandle)
         void release(ThreadHandle aThreadHandle)
         {
         {
-			bbThreadUnregister(aThreadHandle->bbThread);
             CloseHandle(aThreadHandle->thread);
             CloseHandle(aThreadHandle->thread);
             delete aThreadHandle;
             delete aThreadHandle;
         }
         }