@@ -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
108117string_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);
194212DEFINE_LUA_LLHTTP_DATA_CALLBACK (on_header_value );
195213DEFINE_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+
197220int c_on_message_begin (llhttp_t * parser ) { return 0 ; }
198221
199222// request
200223int 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; }
209233int 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
219246int 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
235265int 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