]> git.sesse.net Git - ffmpeg/commitdiff
mem: fix pointer pointer aliasing violations
authorRémi Denis-Courmont <remi@remlab.net>
Mon, 26 Jan 2015 19:17:31 +0000 (21:17 +0200)
committerLuca Barbato <lu_zero@gentoo.org>
Sun, 1 Feb 2015 01:28:40 +0000 (02:28 +0100)
This uses explicit memory copying to read and write pointer to pointers
of arbitrary object types. This works provided that the architecture
uses the same representation for all pointer types (the previous code
made that assumption already anyway).

Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
libavutil/mem.c

index b7bb65c139de522b29647617845d272cf7cc353b..15c28808c1bf0dcc9eeb00c15d0698ba5d5aaf50 100644 (file)
@@ -139,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;
 }
 
@@ -166,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;
 }
 
@@ -197,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)