Skip to content

Commit fdaf384

Browse files
authored
Merge pull request #40 from danielinux/fix-queue-wraparound
queue_pop: properly handle wrap-around
2 parents 71d420e + 9f0cce6 commit fdaf384

2 files changed

Lines changed: 25 additions & 6 deletions

File tree

src/test/unit/unit.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12670,18 +12670,30 @@ END_TEST
1267012670

1267112671
START_TEST(test_queue_pop_wraparound) {
1267212672
struct queue q;
12673+
struct {
12674+
uint8_t buf[8];
12675+
uint8_t guard[4];
12676+
} storage;
1267312677
uint8_t data[] = {9, 10, 11, 12};
12678+
uint8_t expected_guard[] = {0xEE, 0xEE, 0xEE, 0xEE};
1267412679
uint8_t out[4];
1267512680
int len;
12676-
queue_init(&q, mem, memsz, 0x12345678);
12677-
12678-
q.head = memsz - 1;
12679-
q.tail = memsz - 1;
12680-
queue_insert(&q, data, 0, sizeof(data));
12681+
memset(&storage, 0, sizeof(storage));
12682+
memset(storage.guard, 0xEE, sizeof(storage.guard));
12683+
queue_init(&q, storage.buf, sizeof(storage.buf), 0x12345678);
12684+
12685+
/* Manually set a wrapped queue state: tail near end, head near start. */
12686+
q.tail = 6;
12687+
q.head = 2;
12688+
storage.buf[6] = data[0];
12689+
storage.buf[7] = data[1];
12690+
storage.buf[0] = data[2];
12691+
storage.buf[1] = data[3];
1268112692
len = queue_pop(&q, out, sizeof(out));
1268212693
ck_assert_int_eq(len, sizeof(out));
1268312694
ck_assert_mem_eq(out, data, sizeof(data));
1268412695
ck_assert_int_eq(queue_len(&q), 0);
12696+
ck_assert_mem_eq(storage.guard, expected_guard, sizeof(expected_guard));
1268512697
}
1268612698
END_TEST
1268712699

src/wolfip.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -573,11 +573,18 @@ static int queue_insert(struct queue *q, void *data, uint32_t seq, uint32_t len)
573573
static int queue_pop(struct queue *q, void *data, uint32_t len)
574574
{
575575
uint32_t q_len = queue_len(q);
576+
uint32_t first_chunk;
576577
if (q_len == 0)
577578
return -WOLFIP_EAGAIN;
578579
if (len > q_len)
579580
len = q_len;
580-
memcpy(data, (const uint8_t *)q->data + q->tail, len);
581+
if (q->tail + len > q->size) {
582+
first_chunk = q->size - q->tail;
583+
memcpy(data, (const uint8_t *)q->data + q->tail, first_chunk);
584+
memcpy((uint8_t *)data + first_chunk, (const uint8_t *)q->data, len - first_chunk);
585+
} else {
586+
memcpy(data, (const uint8_t *)q->data + q->tail, len);
587+
}
581588
q->tail += len;
582589
q->tail %= q->size;
583590
q->seq_base += len;

0 commit comments

Comments
 (0)