Skip to content

Commit 083b12f

Browse files
committed
fixed several off-by-one bugs
1 parent 8a3903e commit 083b12f

File tree

3 files changed

+41
-41
lines changed

3 files changed

+41
-41
lines changed

libcircle/queue.c

+33-33
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,10 @@ CIRCLE_internal_queue_t* CIRCLE_internal_queue_init(void)
3636
qp->str_count = (int32_t) str_count;
3737

3838
/* Base address of string pool */
39-
qp->base = (char*) malloc(sizeof(char) * \
40-
CIRCLE_MAX_STRING_LEN * \
41-
str_count);
39+
qp->bytes = sizeof(char) * CIRCLE_MAX_STRING_LEN * str_count;
40+
qp->base = (char*) malloc(qp->bytes);
4241
qp->count = 0;
43-
qp->head = 0;
44-
qp->end = qp->base + \
45-
(CIRCLE_MAX_STRING_LEN * str_count);
42+
qp->head = 0;
4643

4744
/* String pointer array */
4845
qp->strings = (uintptr_t*) malloc(sizeof(uintptr_t) * \
@@ -97,8 +94,7 @@ void CIRCLE_internal_queue_dump(CIRCLE_internal_queue_t* qp)
9794
uint32_t i = 0;
9895
char* p = qp->base;
9996

100-
while(p++ != (qp->base + qp->strings[qp->count - 1] + \
101-
strlen(qp->base + qp->strings[qp->count - 1 ]))) {
97+
while(p++ < (qp->base + qp->bytes)) {
10298
if(i++ % 120 == 0) {
10399
LOG(CIRCLE_LOG_DBG, "%c", *p);
104100
}
@@ -155,13 +151,17 @@ int8_t CIRCLE_internal_queue_str_extend(CIRCLE_internal_queue_t* qp, \
155151
* Extend the circle queue size
156152
*
157153
*/
158-
int8_t CIRCLE_internal_queue_extend(CIRCLE_internal_queue_t* qp)
154+
int8_t CIRCLE_internal_queue_extend(CIRCLE_internal_queue_t* qp, size_t new_size)
159155
{
160-
size_t current = (size_t)(qp->end - qp->base);
161-
current += ((size_t)sysconf(_SC_PAGESIZE)) * 4096;
156+
size_t current = qp->bytes;
157+
158+
/* TODO: check for overflow */
159+
while (current < new_size) {
160+
current += ((size_t)sysconf(_SC_PAGESIZE)) * 4096;
161+
}
162162

163163
LOG(CIRCLE_LOG_DBG, "Reallocing queue from [%zd] to [%zd] [%p] -> [%p].", \
164-
(qp->end - qp->base), current, qp->base, qp->base + current);
164+
qp->bytes, current, qp->base, qp->base + current);
165165

166166
qp->base = (char*) realloc(qp->base, current);
167167

@@ -170,7 +170,7 @@ int8_t CIRCLE_internal_queue_extend(CIRCLE_internal_queue_t* qp)
170170
return -1;
171171
}
172172

173-
qp->end = qp->base + current;
173+
qp->bytes = current;
174174
return 0;
175175
}
176176

@@ -190,40 +190,38 @@ int8_t CIRCLE_internal_queue_push(CIRCLE_internal_queue_t* qp, char* str)
190190
}
191191

192192
/* TODO: check that real_len fits within uint32_t */
193-
size_t real_len = strlen(str);
193+
size_t real_len = strlen(str) + 1;
194194
uint32_t len = (uint32_t) real_len;
195195

196196
if(len <= 0) {
197197
LOG(CIRCLE_LOG_ERR, "Attempted to push an empty string onto a queue.");
198198
return -1;
199199
}
200200

201-
if(qp->count > qp->str_count) {
201+
if(len > CIRCLE_MAX_STRING_LEN) {
202+
LOG(CIRCLE_LOG_ERR, \
203+
"Attempted to push a value that was larger than expected.");
204+
return -1;
205+
}
206+
207+
if(qp->count + 1 > qp->str_count) {
202208
LOG(CIRCLE_LOG_DBG, "Extending string array by 4096.");
203209

204-
if(CIRCLE_internal_queue_str_extend(qp, qp->count + 4096) < 0) {
210+
if(CIRCLE_internal_queue_str_extend(qp, qp->count + 1) < 0) {
205211
return -1;
206212
}
207213
}
208214

209-
if(qp->count > 0) {
210-
if(qp->base + qp->strings[qp->count - 1] + \
211-
CIRCLE_MAX_STRING_LEN >= qp->end) {
212-
LOG(CIRCLE_LOG_DBG, \
213-
"The queue is not large enough to add another value.");
215+
size_t new_bytes = (size_t)(qp->head + len) * sizeof(char);
216+
if(new_bytes > qp->bytes) {
217+
LOG(CIRCLE_LOG_DBG, \
218+
"The queue is not large enough to add another value.");
214219

215-
if(CIRCLE_internal_queue_extend(qp) < 0) {
216-
return -1;
217-
}
220+
if(CIRCLE_internal_queue_extend(qp, new_bytes) < 0) {
221+
return -1;
218222
}
219223
}
220224

221-
if(len > CIRCLE_MAX_STRING_LEN) {
222-
LOG(CIRCLE_LOG_ERR, \
223-
"Attempted to push a value that was larger than expected.");
224-
return -1;
225-
}
226-
227225
/* Set our write location to the end of the current strings array. */
228226
qp->strings[qp->count] = qp->head;
229227

@@ -234,7 +232,7 @@ int8_t CIRCLE_internal_queue_push(CIRCLE_internal_queue_t* qp, char* str)
234232
* Make head point to the character after the string (strlen doesn't
235233
* include a trailing null).
236234
*/
237-
qp->head = qp->head + strlen(qp->base + qp->head) + 1;
235+
qp->head += len;
238236

239237
/* Make the head point to the next available memory */
240238
qp->count++;
@@ -269,8 +267,10 @@ int8_t CIRCLE_internal_queue_pop(CIRCLE_internal_queue_t* qp, char* str)
269267
}
270268

271269
/* Copy last element into str */
272-
strcpy(str, qp->base + qp->strings[qp->count - 1]);
273-
qp->count = qp->count - 1;
270+
uintptr_t current = qp->strings[qp->count - 1];
271+
strcpy(str, qp->base + current);
272+
qp->head = current;
273+
qp->count--;
274274

275275
return 0;
276276
}

libcircle/queue.h

+4-5
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@
99
#endif
1010

1111
typedef struct CIRCLE_internal_queue_t {
12-
char* base; /* Base of the memory pool */
13-
char* end; /* End of the memory pool */
14-
uintptr_t next; /* The location of the next string */
12+
char* base; /* Base of the memory pool */
13+
size_t bytes; /* current capacity of queue in bytes */
1514
uintptr_t head; /* The location of the next free byte */
1615
uintptr_t* strings; /* The string data */
1716
int32_t str_count; /* The maximum number of strings the queue can hold */
@@ -29,7 +28,7 @@ void CIRCLE_internal_queue_print(CIRCLE_internal_queue_t* qp);
2928

3029
int8_t CIRCLE_internal_queue_write(CIRCLE_internal_queue_t* qp, int rank);
3130
int8_t CIRCLE_internal_queue_read(CIRCLE_internal_queue_t* qp, int rank);
32-
int8_t CIRCLE_internal_queue_extend(CIRCLE_internal_queue_t* qp);
33-
int8_t CIRCLE_internal_queue_str_extend(CIRCLE_internal_queue_t* qp, int32_t new_size);
31+
int8_t CIRCLE_internal_queue_extend(CIRCLE_internal_queue_t* qp, size_t size);
32+
int8_t CIRCLE_internal_queue_str_extend(CIRCLE_internal_queue_t* qp, int32_t count);
3433

3534
#endif /* QUEUE_H */

libcircle/token.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,9 @@ int32_t CIRCLE_request_work(CIRCLE_internal_queue_t* qp, CIRCLE_state_st* st)
405405
}
406406

407407
/* Make sure our queue is large enough */
408-
while((qp->base + chars) > qp->end) {
409-
if(CIRCLE_internal_queue_extend(qp) < 0) {
408+
size_t new_bytes = (size_t)(qp->head + chars) * sizeof(char);
409+
if(new_bytes > qp->bytes) {
410+
if(CIRCLE_internal_queue_extend(qp, new_bytes) < 0) {
410411
LOG(CIRCLE_LOG_ERR, "Error: Unable to realloc string pool.");
411412
return -1;
412413
}
@@ -442,7 +443,7 @@ int32_t CIRCLE_request_work(CIRCLE_internal_queue_t* qp, CIRCLE_state_st* st)
442443
exit(EXIT_FAILURE);
443444
}
444445

445-
qp->head = qp->strings[qp->count - 1] + strlen(qp->base + qp->strings[qp->count - 1]);
446+
qp->head = qp->strings[qp->count - 1] + strlen(qp->base + qp->strings[qp->count - 1]) + 1;
446447
LOG(CIRCLE_LOG_DBG, "Received %d items from %d", qp->count, source);
447448

448449
return 0;

0 commit comments

Comments
 (0)