Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gst_private.h | 2 ++ dlls/winegstreamer/main.c | 27 +++++++++++++++++++++++++++ dlls/winegstreamer/media_source.c | 8 ++++---- dlls/winegstreamer/quartz_parser.c | 8 ++++---- 4 files changed, 37 insertions(+), 8 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index ebe0bf6f50d..986c8ca695d 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -38,6 +38,8 @@
#include "unixlib.h"
+bool array_reserve(void **elements, size_t *capacity, size_t count, size_t size) DECLSPEC_HIDDEN; + static inline const char *debugstr_time(REFERENCE_TIME time) { ULONGLONG abstime = time >= 0 ? time : -time; diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index c799aa06d1b..d6f19fb4ad1 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -31,6 +31,33 @@ static unixlib_handle_t unix_handle;
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
+bool array_reserve(void **elements, size_t *capacity, size_t count, size_t size) +{ + unsigned int new_capacity, max_capacity; + void *new_elements; + + if (count <= *capacity) + return TRUE; + + max_capacity = ~(SIZE_T)0 / size; + if (count > max_capacity) + return FALSE; + + new_capacity = max(4, *capacity); + while (new_capacity < count && new_capacity <= max_capacity / 2) + new_capacity *= 2; + if (new_capacity < count) + new_capacity = max_capacity; + + if (!(new_elements = realloc(*elements, new_capacity * size))) + return FALSE; + + *elements = new_elements; + *capacity = new_capacity; + + return TRUE; +} + struct wg_parser *wg_parser_create(enum wg_parser_type type, bool unlimited_buffering) { struct wg_parser_create_params params = diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index da898f20f66..703bdd7c57d 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -613,7 +613,7 @@ static DWORD CALLBACK read_thread(void *arg) { struct media_source *source = arg; IMFByteStream *byte_stream = source->byte_stream; - uint32_t buffer_size = 0; + size_t buffer_size = 0; uint64_t file_size; void *data = NULL;
@@ -636,10 +636,10 @@ static DWORD CALLBACK read_thread(void *arg) else if (offset + size >= file_size) size = file_size - offset;
- if (size > buffer_size) + if (!array_reserve(&data, &buffer_size, size, 1)) { - buffer_size = size; - data = realloc(data, size); + free(data); + return 0; }
ret_size = 0; diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c index 6ae1a99a14a..b6655d5da3c 100644 --- a/dlls/winegstreamer/quartz_parser.c +++ b/dlls/winegstreamer/quartz_parser.c @@ -786,7 +786,7 @@ static DWORD CALLBACK read_thread(void *arg) { struct parser *filter = arg; LONGLONG file_size, unused; - uint32_t buffer_size = 0; + size_t buffer_size = 0; void *data = NULL;
IAsyncReader_Length(filter->reader, &file_size, &unused); @@ -807,10 +807,10 @@ static DWORD CALLBACK read_thread(void *arg) else if (offset + size >= file_size) size = file_size - offset;
- if (size > buffer_size) + if (!array_reserve(&data, &buffer_size, size, 1)) { - buffer_size = size; - data = realloc(data, size); + free(data); + return 0; }
hr = IAsyncReader_SyncRead(filter->reader, offset, size, data);