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;