Zebediah Figura : winegstreamer: Use array_reserve() to reallocate read buffers.

Alexandre Julliard julliard at winehq.org
Wed Oct 6 15:51:39 CDT 2021


Module: wine
Branch: master
Commit: 59997c355fdc9cb5857c767b3bf16c9513b3d1f3
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=59997c355fdc9cb5857c767b3bf16c9513b3d1f3

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Wed Oct  6 11:46:33 2021 -0500

winegstreamer: Use array_reserve() to reallocate read buffers.

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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);




More information about the wine-cvs mailing list