Skip to content

Commit 308ca6d

Browse files
committed
Fix missing null-pointer checks in queue API
The queue_peek() and queue_dequeue() functions did not check for null before dereferencing the queue pointer, causing potential undefined behavior. This patch adds explicit null checks in queue.h to align its safety behavior with list.h. Redundant checks in queue.c were removed, and queue_enqueue() was updated to return an error when given a null pointer. As part of this update, queue_count() now treats a null pointer as an empty queue and returns 0, ensuring safe behavior even when invalid pointers are passed.
1 parent 23f4277 commit 308ca6d

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

include/lib/queue.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#pragma once
1212

1313
#include <lib/libc.h>
14+
#include "private/utils.h"
1415

1516
/* State is managed entirely by head/tail indices. The capacity is always
1617
* a power of two to allow for efficient bitwise masking instead of a more
@@ -46,19 +47,27 @@ int32_t queue_destroy(queue_t *q);
4647
/* Checks if the queue is empty. */
4748
static inline bool queue_is_empty(const queue_t *q)
4849
{
49-
return q->head == q->tail;
50+
return !q || q->head == q->tail;
5051
}
5152

52-
/* Returns the number of elements currently in the queue. */
53+
/* Returns the number of elements currently in the queue.
54+
*
55+
* If the queue pointer is NULL, it is treated as an empty queue
56+
* and this function returns 0. This ensures safe behavior even
57+
* when invalid pointers are passed.
58+
*/
5359
static inline uint32_t queue_count(const queue_t *q)
5460
{
61+
/* Treat NULL queue as empty to prevent undefined behavior */
62+
if (unlikely(!q))
63+
return 0u;
5564
return (q->tail - q->head + q->size) & q->mask;
5665
}
5766

5867
/* Checks if the queue is full. */
5968
static inline bool queue_is_full(const queue_t *q)
6069
{
61-
return ((q->tail + 1) & q->mask) == q->head;
70+
return q && (((q->tail + 1) & q->mask) == q->head);
6271
}
6372

6473
/* Adds an element to the tail of the queue (FIFO). */

lib/queue.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ queue_t *queue_create(int32_t capacity)
3737
int32_t queue_destroy(queue_t *q)
3838
{
3939
/* Refuse to destroy a non-empty queue. */
40-
if (!q || !queue_is_empty(q))
40+
if (!queue_is_empty(q))
4141
return ERR_FAIL;
4242

4343
free(q->buf);
@@ -48,8 +48,10 @@ int32_t queue_destroy(queue_t *q)
4848
/* Adds an element to the tail of the queue. */
4949
int32_t queue_enqueue(queue_t *q, void *ptr)
5050
{
51-
/* The queue can only store up to 'size - 1' items. */
52-
if (queue_is_full(q))
51+
/* Reject null pointer or enqueue into a full queue.
52+
* The queue can only store up to 'size - 1' items.
53+
*/
54+
if (!q || queue_is_full(q))
5355
return ERR_FAIL;
5456

5557
q->buf[q->tail] = ptr;

0 commit comments

Comments
 (0)