diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index ebe0bf6f50d233579da0ce3b965265a4bc582379..986c8ca695d930851244674d4962ab9b4ed6e592 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 c799aa06d1b246f7911bdc1e6dd6f4f09b8015de..d6f19fb4ad1107546625bc38d6ba1ccc5e11aa79 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 da898f20f6654ae9a108172c990bdb0daa9fb1ef..703bdd7c57da96cab58c6ac2d021c942f7e037dd 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 6ae1a99a14a62bb8e78fdec0cb093bd2d4516a3c..b6655d5da3cdb07b461922545c4a9ed3891e5917 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);