Skip to content

Commit 75d2b6d

Browse files
committed
Track an error state on yajl_buf
1 parent 7168bd7 commit 75d2b6d

File tree

1 file changed

+51
-2
lines changed

1 file changed

+51
-2
lines changed

ext/yajl/yajl_buf.c

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,35 +38,82 @@
3838

3939
#define YAJL_BUF_INIT_SIZE 2048
4040

41+
typedef enum {
42+
yajl_buf_ok = 0,
43+
yajl_buf_alloc_failed,
44+
yajl_buf_overflow
45+
} yajl_buf_state;
46+
4147
struct yajl_buf_t {
48+
yajl_buf_state state;
4249
unsigned int len;
4350
unsigned int used;
4451
unsigned char * data;
4552
yajl_alloc_funcs * alloc;
4653
};
4754

55+
#include <stdio.h>
56+
57+
static
58+
yajl_buf_state yajl_buf_set_error(yajl_buf buf, yajl_buf_state err)
59+
{
60+
buf->state = err;
61+
62+
// free and clear all data from the buffer
63+
YA_FREE(buf->alloc, buf->data);
64+
buf->len = 0;
65+
buf->data = 0;
66+
buf->used = 0;
67+
68+
return err;
69+
}
70+
4871
static
49-
void yajl_buf_ensure_available(yajl_buf buf, unsigned int want)
72+
yajl_buf_state yajl_buf_ensure_available(yajl_buf buf, unsigned int want)
5073
{
5174
unsigned int need;
5275

5376
assert(buf != NULL);
5477

78+
if (buf->state != yajl_buf_ok) {
79+
return buf->state;
80+
}
81+
5582
/* first call */
5683
if (buf->data == NULL) {
5784
buf->len = YAJL_BUF_INIT_SIZE;
5885
buf->data = (unsigned char *) YA_MALLOC(buf->alloc, buf->len);
86+
if (buf->data == NULL) {
87+
return yajl_buf_set_error(buf, yajl_buf_overflow);
88+
}
89+
5990
buf->data[0] = 0;
6091
}
6192

93+
if (want == 0) {
94+
return yajl_buf_ok;
95+
}
96+
6297
need = buf->len;
6398

6499
while (want >= (need - buf->used)) need <<= 1;
65100

101+
// overflow
102+
if (need == 0) {
103+
return yajl_buf_set_error(buf, yajl_buf_overflow);
104+
}
105+
66106
if (need != buf->len) {
67107
buf->data = (unsigned char *) YA_REALLOC(buf->alloc, buf->data, need);
108+
109+
if (buf->data == NULL) {
110+
return yajl_buf_set_error(buf, yajl_buf_overflow);
111+
}
112+
68113
buf->len = need;
69114
}
115+
116+
return yajl_buf_ok;
70117
}
71118

72119
yajl_buf yajl_buf_alloc(yajl_alloc_funcs * alloc)
@@ -86,7 +133,9 @@ void yajl_buf_free(yajl_buf buf)
86133

87134
void yajl_buf_append(yajl_buf buf, const void * data, unsigned int len)
88135
{
89-
yajl_buf_ensure_available(buf, len);
136+
if (yajl_buf_ensure_available(buf, len)) {
137+
return;
138+
}
90139
if (len > 0) {
91140
assert(data != NULL);
92141
memcpy(buf->data + buf->used, data, len);

0 commit comments

Comments
 (0)