@@ -190,8 +190,20 @@ static BaseType_t copyItemToRingbufAllowSplit(ringbuf_t *rb, uint8_t *buffer, si
190190 memcpy (rb -> write_ptr , buffer , rem_len );
191191 //Update vars so the code later on will write the rest of the data.
192192 buffer += rem_len ;
193- rbuffer_size -= rem_len ;
194193 buffer_size -= rem_len ;
194+ //Re-adjust the rbuffer value to be 4 byte aligned
195+ rbuffer_size = (buffer_size + 3 )& ~3 ;
196+ //It is possible that we are here because we checked for 4byte aligned
197+ //size, but actual data was smaller.
198+ //Eg. For buffer_size = 34, rbuffer_size will be 36. Suppose we had only
199+ //42 bytes of memory available, the top level check will fail, as it will
200+ //check for availability of 36 + 8 = 44 bytes.
201+ //However, the 42 bytes available memory is sufficient for 34 + 8 bytes data
202+ //and so, we can return after writing the data. Hence, this check
203+ if (buffer_size == 0 ) {
204+ rb -> write_ptr = rb -> data ;
205+ return pdTRUE ;
206+ }
195207 } else {
196208 //Huh, only the header fit. Mark as dummy so the receive function doesn't receive
197209 //an useless zero-byte packet.
@@ -286,7 +298,10 @@ static uint8_t *getItemFromRingbufDefault(ringbuf_t *rb, size_t *length, int wan
286298 //...and move the read pointer past the data.
287299 rb -> read_ptr += sizeof (buf_entry_hdr_t )+ ((hdr -> len + 3 )& ~3 );
288300 //The buffer will wrap around if we don't have room for a header anymore.
289- if ((rb -> data + rb -> size ) - rb -> read_ptr < sizeof (buf_entry_hdr_t )) {
301+ //Integer typecasting is used because the first operand can result into a -ve
302+ //value for cases wherein the ringbuffer size is not a multiple of 4, but the
303+ //implementation logic aligns read_ptr to 4-byte boundary
304+ if ((int )((rb -> data + rb -> size ) - rb -> read_ptr ) < (int )sizeof (buf_entry_hdr_t )) {
290305 rb -> read_ptr = rb -> data ;
291306 }
292307 return ret ;
@@ -355,12 +370,20 @@ static void returnItemToRingbufDefault(ringbuf_t *rb, void *item) {
355370 rb -> free_ptr = rb -> data ;
356371 } else {
357372 //Skip past item
373+ rb -> free_ptr += sizeof (buf_entry_hdr_t );
374+ //Check if the free_ptr overshoots the buffer.
375+ //Checking this before aligning free_ptr since it is possible that alignment
376+ //will cause pointer to overshoot, if the ringbuf size is not a multiple of 4
377+ configASSERT (rb -> free_ptr + hdr -> len <=rb -> data + rb -> size );
378+ //Align free_ptr to 4 byte boundary. Overshoot condition will result in wrap around below
358379 size_t len = (hdr -> len + 3 )& ~3 ;
359- rb -> free_ptr += len + sizeof (buf_entry_hdr_t );
360- configASSERT (rb -> free_ptr <=rb -> data + rb -> size );
380+ rb -> free_ptr += len ;
361381 }
362382 //The buffer will wrap around if we don't have room for a header anymore.
363- if ((rb -> data + rb -> size )- rb -> free_ptr < sizeof (buf_entry_hdr_t )) {
383+ //Integer typecasting is used because the first operand can result into a -ve
384+ //value for cases wherein the ringbuffer size is not a multiple of 4, but the
385+ //implementation logic aligns free_ptr to 4-byte boundary
386+ if ((int )((rb -> data + rb -> size )- rb -> free_ptr ) < (int )sizeof (buf_entry_hdr_t )) {
364387 rb -> free_ptr = rb -> data ;
365388 }
366389 //The free_ptr can not exceed read_ptr, otherwise write_ptr might overwrite read_ptr.
0 commit comments