shithub: dav1d

Download patch

ref: c52cc17a7e39b81b9c91b5e51f54716909fd108a
parent: 9f17489c4de0035f4262ea39a2193c8ca82c1035
author: Janne Grunau <janne-vlc@jannau.net>
date: Sun Oct 28 17:09:54 EDT 2018

API: constify Dav1dData and dav1d_data_wrap()

Fix #120.

--- a/include/dav1d/data.h
+++ b/include/dav1d/data.h
@@ -34,7 +34,7 @@
 #include "common.h"
 
 typedef struct Dav1dData {
-    uint8_t *data; ///< data pointer
+    const uint8_t *data; ///< data pointer
     size_t sz; ///< data size
     struct Dav1dRef *ref; ///< allocation origin
 } Dav1dData;
@@ -45,9 +45,9 @@
  * @param data Input context.
  * @param   sz Size of the data that should be allocated.
  *
- * @return 0 on success. A negative errno value on error.
+ * @return Pointer to the allocated bufferon success. NULL on error.
  */
-DAV1D_API int dav1d_data_create(Dav1dData *data, size_t sz);
+DAV1D_API uint8_t * dav1d_data_create(Dav1dData *data, size_t sz);
 
 /**
  * Wrap an existing data array.
@@ -63,8 +63,8 @@
  *
  * @return 0 on success. A negative errno value on error.
  */
-DAV1D_API int dav1d_data_wrap(Dav1dData *data, uint8_t *buf, size_t sz,
-                              void (*free_callback)(uint8_t *buf, void *user_data),
+DAV1D_API int dav1d_data_wrap(Dav1dData *data, const uint8_t *buf, size_t sz,
+                              void (*free_callback)(const uint8_t *buf, void *user_data),
                               void *user_data);
 
 /**
--- a/src/data.c
+++ b/src/data.c
@@ -37,19 +37,19 @@
 
 #include "src/ref.h"
 
-int dav1d_data_create(Dav1dData *const buf, const size_t sz) {
-    validate_input_or_ret(buf != NULL, -EINVAL);
+uint8_t * dav1d_data_create(Dav1dData *const buf, const size_t sz) {
+    validate_input_or_ret(buf != NULL, NULL);
 
     buf->ref = dav1d_ref_create(sz);
-    if (!buf->ref) return -ENOMEM;
-    buf->data = buf->ref->data;
+    if (!buf->ref) return NULL;
+    buf->data = buf->ref->const_data;
     buf->sz = sz;
 
-    return 0;
+    return buf->ref->data;
 }
 
-int dav1d_data_wrap(Dav1dData *const buf, uint8_t *const ptr, const size_t sz,
-                    void (*free_callback)(uint8_t *data, void *user_data),
+int dav1d_data_wrap(Dav1dData *const buf, const uint8_t *const ptr, const size_t sz,
+                    void (*free_callback)(const uint8_t *data, void *user_data),
                     void *user_data)
 {
     validate_input_or_ret(buf != NULL, -EINVAL);
--- a/src/picture.c
+++ b/src/picture.c
@@ -86,14 +86,15 @@
 struct pic_ctx_context {
     Dav1dPicAllocator allocator;
     void *allocator_data;
+    uint8_t *data;
     void *extra_ptr; /* MUST BE AT THE END */
 };
 
-static void free_buffer(uint8_t *data, void *user_data)
+static void free_buffer(const uint8_t *data, void *user_data)
 {
     struct pic_ctx_context *pic_ctx = user_data;
 
-    pic_ctx->allocator.release_picture_callback(data,
+    pic_ctx->allocator.release_picture_callback(pic_ctx->data,
                                                 pic_ctx->allocator_data,
                                                 pic_ctx->allocator.cookie);
     free(pic_ctx);
@@ -133,6 +134,7 @@
 
     pic_ctx->allocator = *p_allocator;
     pic_ctx->allocator_data = p->allocator_data;
+    pic_ctx->data = p->data[0];
 
     if (!(p->ref = dav1d_ref_wrap(p->data[0], free_buffer, pic_ctx))) {
         p_allocator->release_picture_callback(p->data[0], p->allocator_data,
--- a/src/ref.c
+++ b/src/ref.c
@@ -31,8 +31,9 @@
 
 #include "src/ref.h"
 
-static void default_free_callback(uint8_t *const data, void *const user_data) {
-    dav1d_free_aligned(data);
+static void default_free_callback(const uint8_t *const data, void *const user_data) {
+    assert(data == user_data);
+    dav1d_free_aligned(user_data);
 }
 
 Dav1dRef *dav1d_ref_create(const size_t size) {
@@ -42,7 +43,7 @@
         return NULL;
     }
 
-    res = dav1d_ref_wrap(data, default_free_callback, NULL);
+    res = dav1d_ref_wrap(data, default_free_callback, data);
     if (!res) {
         free(data);
     }
@@ -50,14 +51,16 @@
     return res;
 }
 
-Dav1dRef *dav1d_ref_wrap(uint8_t *const ptr,
-                         void (*free_callback)(uint8_t *data, void *user_data),
+Dav1dRef *dav1d_ref_wrap(const uint8_t *const ptr,
+                         void (*free_callback)(const uint8_t *data, void *user_data),
                          void *user_data)
 {
     Dav1dRef *res = malloc(sizeof(Dav1dRef));
     if (!res) return NULL;
 
-    res->data = ptr;
+    if (ptr == user_data)
+        res->data = user_data;
+    res->const_data = ptr;
     atomic_init(&res->ref_cnt, 1);
     res->free_callback = free_callback;
     res->user_data = user_data;
@@ -71,7 +74,7 @@
 
 void dav1d_ref_dec(Dav1dRef *const ref) {
     if (atomic_fetch_sub(&ref->ref_cnt, 1) == 1) {
-        ref->free_callback(ref->data, ref->user_data);
+        ref->free_callback(ref->const_data, ref->user_data);
         free(ref);
     }
 }
--- a/src/ref.h
+++ b/src/ref.h
@@ -35,14 +35,15 @@
 
 struct Dav1dRef {
     void *data;
+    const void *const_data;
     atomic_int ref_cnt;
-    void (*free_callback)(uint8_t *data, void *user_data);
+    void (*free_callback)(const uint8_t *data, void *user_data);
     void *user_data;
 };
 
 Dav1dRef *dav1d_ref_create(size_t size);
-Dav1dRef *dav1d_ref_wrap(uint8_t *ptr,
-                         void (*free_callback)(uint8_t *data, void *user_data),
+Dav1dRef *dav1d_ref_wrap(const uint8_t *ptr,
+                         void (*free_callback)(const uint8_t *data, void *user_data),
                          void *user_data);
 void dav1d_ref_inc(Dav1dRef *ref);
 void dav1d_ref_dec(Dav1dRef *ref);
--- a/tests/libfuzzer/dav1d_fuzzer.c
+++ b/tests/libfuzzer/dav1d_fuzzer.c
@@ -65,6 +65,7 @@
 
     while (ptr <= data + size - 12) {
         Dav1dData buf;
+        uint8_t *p;
 
         size_t frame_size = r32le(ptr);
         ptr += 12;
@@ -73,9 +74,9 @@
             break;
 
         // copy frame data to a new buffer to catch reads past the end of input
-        err = dav1d_data_create(&buf, frame_size);
-        if (err) goto cleanup;
-        memcpy(buf.data, ptr, frame_size);
+        p = dav1d_data_create(&buf, frame_size);
+        if (!p) goto cleanup;
+        memcpy(p, ptr, frame_size);
         ptr += frame_size;
 
         do {
--- a/tools/input/ivf.c
+++ b/tools/input/ivf.c
@@ -86,6 +86,7 @@
 
 static int ivf_read(IvfInputContext *const c, Dav1dData *const buf) {
     uint8_t data[4];
+    uint8_t *ptr;
     int res;
 
     if ((res = fread(data, 4, 1, c->f)) != 1)
@@ -92,8 +93,9 @@
         return -1; // EOF
     fseek(c->f, 8, SEEK_CUR); // skip timestamp
     const ptrdiff_t sz = rl32(data);
-    dav1d_data_create(buf, sz);
-    if ((res = fread(buf->data, sz, 1, c->f)) != 1) {
+    ptr = dav1d_data_create(buf, sz);
+    if (!ptr) return -1;
+    if ((res = fread(ptr, sz, 1, c->f)) != 1) {
         fprintf(stderr, "Failed to read frame data: %s\n", strerror(errno));
         dav1d_data_unref(buf);
         return -1;