]> git.sesse.net Git - ffmpeg/blobdiff - libavutil/mem.c
tls_gnutls: fix hang on disconnection
[ffmpeg] / libavutil / mem.c
index b84020c0f9f7ad40de8bdcb9e397970587d404db..15c28808c1bf0dcc9eeb00c15d0698ba5d5aaf50 100644 (file)
@@ -35,6 +35,7 @@
 #endif
 
 #include "avutil.h"
+#include "common.h"
 #include "intreadwrite.h"
 #include "mem.h"
 
@@ -138,21 +139,22 @@ void *av_realloc(void *ptr, size_t size)
 
 int av_reallocp(void *ptr, size_t size)
 {
-    void **ptrptr = ptr;
-    void *ret;
+    void *val;
 
     if (!size) {
         av_freep(ptr);
         return 0;
     }
-    ret = av_realloc(*ptrptr, size);
 
-    if (!ret) {
+    memcpy(&val, ptr, sizeof(val));
+    val = av_realloc(val, size);
+
+    if (!val) {
         av_freep(ptr);
         return AVERROR(ENOMEM);
     }
 
-    *ptrptr = ret;
+    memcpy(ptr, &val, sizeof(val));
     return 0;
 }
 
@@ -165,20 +167,23 @@ void *av_realloc_array(void *ptr, size_t nmemb, size_t size)
 
 int av_reallocp_array(void *ptr, size_t nmemb, size_t size)
 {
-    void **ptrptr = ptr;
-    void *ret;
+    void *val;
+
     if (!size || nmemb >= INT_MAX / size)
         return AVERROR(ENOMEM);
     if (!nmemb) {
         av_freep(ptr);
         return 0;
     }
-    ret = av_realloc(*ptrptr, nmemb * size);
-    if (!ret) {
+
+    memcpy(&val, ptr, sizeof(val));
+    val = av_realloc(val, nmemb * size);
+    if (!val) {
         av_freep(ptr);
         return AVERROR(ENOMEM);
     }
-    *ptrptr = ret;
+
+    memcpy(ptr, &val, sizeof(val));
     return 0;
 }
 
@@ -196,9 +201,11 @@ void av_free(void *ptr)
 
 void av_freep(void *arg)
 {
-    void **ptr = (void **)arg;
-    av_free(*ptr);
-    *ptr = NULL;
+    void *val;
+
+    memcpy(&val, arg, sizeof(val));
+    memcpy(arg, &(void *){ NULL }, sizeof(val));
+    av_free(val);
 }
 
 void *av_mallocz(size_t size)
@@ -214,13 +221,33 @@ char *av_strdup(const char *s)
     char *ptr = NULL;
     if (s) {
         int len = strlen(s) + 1;
-        ptr = av_malloc(len);
+        ptr = av_realloc(NULL, len);
         if (ptr)
             memcpy(ptr, s, len);
     }
     return ptr;
 }
 
+char *av_strndup(const char *s, size_t len)
+{
+    char *ret = NULL, *end;
+
+    if (!s)
+        return NULL;
+
+    end = memchr(s, 0, len);
+    if (end)
+        len = end - s;
+
+    ret = av_realloc(NULL, len + 1);
+    if (!ret)
+        return NULL;
+
+    memcpy(ret, s, len);
+    ret[len] = 0;
+    return ret;
+}
+
 static void fill16(uint8_t *dst, int len)
 {
     uint32_t v = AV_RN16(dst - 2);
@@ -344,3 +371,35 @@ void av_memcpy_backptr(uint8_t *dst, int back, int cnt)
             *dst = *src;
     }
 }
+
+void *av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
+{
+    if (min_size < *size)
+        return ptr;
+
+    min_size = FFMAX(17 * min_size / 16 + 32, min_size);
+
+    ptr = av_realloc(ptr, min_size);
+    /* we could set this to the unmodified min_size but this is safer
+     * if the user lost the ptr and uses NULL now
+     */
+    if (!ptr)
+        min_size = 0;
+
+    *size = min_size;
+
+    return ptr;
+}
+
+void av_fast_malloc(void *ptr, unsigned int *size, size_t min_size)
+{
+    void **p = ptr;
+    if (min_size < *size)
+        return;
+    min_size = FFMAX(17 * min_size / 16 + 32, min_size);
+    av_free(*p);
+    *p = av_malloc(min_size);
+    if (!*p)
+        min_size = 0;
+    *size = min_size;
+}