Skip to content

Commit b65b704

Browse files
committed
fix(core): handle realloc failure
1 parent 98e091e commit b65b704

File tree

1 file changed

+43
-12
lines changed

1 file changed

+43
-12
lines changed

llhttp/core/main.c

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -89,20 +89,29 @@ string *_lua_llhttp__string_reset(string *str) {
8989
return str;
9090
}
9191

92-
void _lua_llhttp__string_append(string *str, const char *buf, size_t len) {
92+
// returns `0` if successful, `-1` otherwise.
93+
int _lua_llhttp__string_append(string *str, const char *buf, size_t len) {
9394
size_t new_len = str->len + len;
9495
if (str->size < new_len) {
9596
size_t new_size = str->size * 2;
9697
while (new_size < new_len) {
9798
new_size = new_size * 2;
9899
}
99-
str->buf = realloc(str->buf, new_size + 1);
100+
101+
void *new_buf = realloc(str->buf, new_size + 1);
102+
if (new_buf == NULL) {
103+
return -1;
104+
}
105+
106+
str->buf = new_buf;
100107
str->size = new_size;
101108
}
102109

103110
memcpy(str->buf + str->len, buf, len);
104111
str->len = new_len;
105112
str->buf[str->len] = '\0';
113+
114+
return 0;
106115
}
107116

108117
string_list *_lua_llhttp__string_list_new() {
@@ -127,13 +136,22 @@ string_list *_lua_llhttp__string_list_reset(string_list *list) {
127136
return list;
128137
}
129138

130-
void _lua_llhttp__string_list_add(string_list *list) {
139+
// returns `0` if successful, `-1` otherwise.
140+
int _lua_llhttp__string_list_add(string_list *list) {
131141
if (list->size == list->len + 1) {
132-
list->items = realloc(list->items, 2 * list->size * sizeof(list->items));
142+
void *new_items =
143+
realloc(list->items, 2 * list->size * sizeof(list->items));
144+
if (new_items == NULL) {
145+
return -1;
146+
}
147+
148+
list->items = new_items;
133149
list->size = 2 * list->size;
134150
}
135151

136152
list->items[list->len++] = _lua_llhttp__string_new();
153+
154+
return 0;
137155
}
138156

139157
#define LUA_LLHTTP_META "llhttp.core.lua_llhttp"
@@ -194,12 +212,18 @@ DEFINE_LUA_LLHTTP_DATA_CALLBACK(on_header_field);
194212
DEFINE_LUA_LLHTTP_DATA_CALLBACK(on_header_value);
195213
DEFINE_LUA_LLHTTP_DATA_CALLBACK(on_body);
196214

215+
#define LUA_LLHTTP_HANDLE_C_CB_OOM(CB_NAME, OOM_ERRNO, FUNCTION_CALL) \
216+
if (OOM_ERRNO == FUNCTION_CALL) { \
217+
return luaL_error(data->llhttp->L, "out of memory (at %s)", CB_NAME); \
218+
}
219+
197220
int c_on_message_begin(llhttp_t *parser) { return 0; }
198221

199222
// request
200223
int c_on_url(llhttp_t *parser, const char *at, size_t length) {
201224
lua_llhttp_data_t *data = (lua_llhttp_data_t *)parser->data;
202-
_lua_llhttp__string_append(data->url, at, length);
225+
LUA_LLHTTP_HANDLE_C_CB_OOM("on_url", -1,
226+
_lua_llhttp__string_append(data->url, at, length));
203227
return 0;
204228
}
205229

@@ -209,20 +233,26 @@ int c_on_status(llhttp_t *parser, const char *at, size_t length) { return 0; }
209233
int c_on_header_field(llhttp_t *parser, const char *at, size_t length) {
210234
lua_llhttp_data_t *data = (lua_llhttp_data_t *)parser->data;
211235
if (data->headers->len % 2 == 0) {
212-
_lua_llhttp__string_list_add(data->headers);
236+
LUA_LLHTTP_HANDLE_C_CB_OOM("on_header_field", -1,
237+
_lua_llhttp__string_list_add(data->headers));
213238
}
214-
_lua_llhttp__string_append(data->headers->items[data->headers->len - 1], at,
215-
length);
239+
LUA_LLHTTP_HANDLE_C_CB_OOM(
240+
"on_header_field", -1,
241+
_lua_llhttp__string_append(data->headers->items[data->headers->len - 1],
242+
at, length));
216243
return 0;
217244
}
218245

219246
int c_on_header_value(llhttp_t *parser, const char *at, size_t length) {
220247
lua_llhttp_data_t *data = (lua_llhttp_data_t *)parser->data;
221248
if (data->headers->len % 2 == 1) {
222-
_lua_llhttp__string_list_add(data->headers);
249+
LUA_LLHTTP_HANDLE_C_CB_OOM("on_header_value", -1,
250+
_lua_llhttp__string_list_add(data->headers));
223251
}
224-
_lua_llhttp__string_append(data->headers->items[data->headers->len - 1], at,
225-
length);
252+
LUA_LLHTTP_HANDLE_C_CB_OOM(
253+
"on_header_value", -1,
254+
_lua_llhttp__string_append(data->headers->items[data->headers->len - 1],
255+
at, length));
226256
return 0;
227257
}
228258

@@ -234,7 +264,8 @@ int c_on_headers_complete(llhttp_t *parser) {
234264

235265
int c_on_body(llhttp_t *parser, const char *at, size_t length) {
236266
lua_llhttp_data_t *data = (lua_llhttp_data_t *)parser->data;
237-
_lua_llhttp__string_append(data->body, at, length);
267+
LUA_LLHTTP_HANDLE_C_CB_OOM(
268+
"on_body", -1, _lua_llhttp__string_append(data->body, at, length));
238269
if (parser->content_length > 0 &&
239270
data->llhttp->body_chunk_size_threshold <= data->body->len) {
240271
data->llhttp->pause_cause = PAUSE_CAUSE_BODY_CHUNK_READY;

0 commit comments

Comments
 (0)