From 2975be9588f57409069280916174dc5d695b47e1 Mon Sep 17 00:00:00 2001 From: GoaLitiuM Date: Wed, 25 Oct 2017 06:11:36 +0300 Subject: [PATCH] Fix integer overflow in ring buffer --- src/atomics.h | 8 ++++++++ src/ring_buffer.c | 10 +++++----- src/ring_buffer.h | 4 ++-- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/atomics.h b/src/atomics.h index a395f50..bddc780 100644 --- a/src/atomics.h +++ b/src/atomics.h @@ -31,6 +31,10 @@ struct SoundIoAtomicFlag { std::atomic_flag x; }; +struct SoundIoAtomicULong { + std::atomic x; +}; + #define SOUNDIO_ATOMIC_LOAD(a) (a.x.load()) #define SOUNDIO_ATOMIC_FETCH_ADD(a, delta) (a.x.fetch_add(delta)) #define SOUNDIO_ATOMIC_STORE(a, value) (a.x.store(value)) @@ -59,6 +63,10 @@ struct SoundIoAtomicFlag { atomic_flag x; }; +struct SoundIoAtomicULong { + atomic_ulong x; +}; + #define SOUNDIO_ATOMIC_LOAD(a) atomic_load(&a.x) #define SOUNDIO_ATOMIC_FETCH_ADD(a, delta) atomic_fetch_add(&a.x, delta) #define SOUNDIO_ATOMIC_STORE(a, value) atomic_store(&a.x, value) diff --git a/src/ring_buffer.c b/src/ring_buffer.c index 969bb41..0c27b8b 100644 --- a/src/ring_buffer.c +++ b/src/ring_buffer.c @@ -43,7 +43,7 @@ int soundio_ring_buffer_capacity(struct SoundIoRingBuffer *rb) { } char *soundio_ring_buffer_write_ptr(struct SoundIoRingBuffer *rb) { - long write_offset = SOUNDIO_ATOMIC_LOAD(rb->write_offset); + unsigned long write_offset = SOUNDIO_ATOMIC_LOAD(rb->write_offset); return rb->mem.address + (write_offset % rb->capacity); } @@ -53,7 +53,7 @@ void soundio_ring_buffer_advance_write_ptr(struct SoundIoRingBuffer *rb, int cou } char *soundio_ring_buffer_read_ptr(struct SoundIoRingBuffer *rb) { - long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); + unsigned long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); return rb->mem.address + (read_offset % rb->capacity); } @@ -65,8 +65,8 @@ void soundio_ring_buffer_advance_read_ptr(struct SoundIoRingBuffer *rb, int coun int soundio_ring_buffer_fill_count(struct SoundIoRingBuffer *rb) { // Whichever offset we load first might have a smaller value. So we load // the read_offset first. - long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); - long write_offset = SOUNDIO_ATOMIC_LOAD(rb->write_offset); + unsigned long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); + unsigned long write_offset = SOUNDIO_ATOMIC_LOAD(rb->write_offset); int count = write_offset - read_offset; assert(count >= 0); assert(count <= rb->capacity); @@ -78,7 +78,7 @@ int soundio_ring_buffer_free_count(struct SoundIoRingBuffer *rb) { } void soundio_ring_buffer_clear(struct SoundIoRingBuffer *rb) { - long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); + unsigned long read_offset = SOUNDIO_ATOMIC_LOAD(rb->read_offset); SOUNDIO_ATOMIC_STORE(rb->write_offset, read_offset); } diff --git a/src/ring_buffer.h b/src/ring_buffer.h index c230292..61b8dcd 100644 --- a/src/ring_buffer.h +++ b/src/ring_buffer.h @@ -13,8 +13,8 @@ struct SoundIoRingBuffer { struct SoundIoOsMirroredMemory mem; - struct SoundIoAtomicLong write_offset; - struct SoundIoAtomicLong read_offset; + struct SoundIoAtomicULong write_offset; + struct SoundIoAtomicULong read_offset; int capacity; };