@@ -54,16 +54,16 @@ static int callback_error(nghttp2_session *session, int lib_error_code,
5454static ssize_t callback_send (nghttp2_session * session , const uint8_t * data ,
5555 size_t length , int flags , void * user_data )
5656{
57- int rv = 0 ;
57+ ssize_t rv = 0 ;
5858 struct sh2lib_handle * hd = user_data ;
5959
60- int copy_offset = 0 ;
61- int pending_data = length ;
60+ size_t copy_offset = 0 ;
61+ size_t pending_data = length ;
6262
6363 /* Send data in 1000 byte chunks */
64- while (copy_offset != length ) {
65- int chunk_len = pending_data > 1000 ? 1000 : pending_data ;
66- int subrv = callback_send_inner (hd , data + copy_offset , chunk_len );
64+ while (copy_offset < length ) {
65+ size_t chunk_len = pending_data > 1000 ? 1000 : pending_data ;
66+ ssize_t subrv = callback_send_inner (hd , data + copy_offset , chunk_len );
6767 if (subrv <= 0 ) {
6868 if (copy_offset == 0 ) {
6969 /* If no data is transferred, send the error code */
@@ -143,10 +143,8 @@ static int callback_on_frame_send(nghttp2_session *session,
143143 ESP_LOGD (TAG , "[frame-send] C ----------------------------> S (HEADERS)" );
144144#if DBG_FRAME_SEND
145145 ESP_LOGD (TAG , "[frame-send] headers nv-len = %d" , frame -> headers .nvlen );
146- const nghttp2_nv * nva = frame -> headers .nva ;
147- size_t i ;
148- for (i = 0 ; i < frame -> headers .nvlen ; ++ i ) {
149- ESP_LOGD (TAG , "[frame-send] %s : %s" , nva [i ].name , nva [i ].value );
146+ for (size_t i = 0 ; i < frame -> headers .nvlen ; ++ i ) {
147+ ESP_LOGD (TAG , "[frame-send] %s : %s" , frame -> headers .nva [i ].name , frame -> headers .nva [i ].value );
150148 }
151149#endif
152150 }
@@ -228,7 +226,11 @@ static int do_http2_connect(struct sh2lib_handle *hd)
228226{
229227 int ret ;
230228 nghttp2_session_callbacks * callbacks ;
231- nghttp2_session_callbacks_new (& callbacks );
229+ ret = nghttp2_session_callbacks_new (& callbacks );
230+ if (ret != 0 ) {
231+ ESP_LOGE (TAG , "[sh2-connect] Failed to create session callbacks" );
232+ return -1 ;
233+ }
232234 nghttp2_session_callbacks_set_error_callback2 (callbacks , callback_error );
233235 nghttp2_session_callbacks_set_send_callback (callbacks , callback_send );
234236 nghttp2_session_callbacks_set_recv_callback (callbacks , callback_recv );
@@ -251,20 +253,23 @@ static int do_http2_connect(struct sh2lib_handle *hd)
251253 ret = nghttp2_submit_settings (hd -> http2_sess , NGHTTP2_FLAG_NONE , NULL , 0 );
252254 if (ret != 0 ) {
253255 ESP_LOGE (TAG , "[sh2-connect] Submit settings failed" );
256+ /* Clean up session to prevent memory leak on error path */
257+ nghttp2_session_del (hd -> http2_sess );
258+ hd -> http2_sess = NULL ;
254259 return -1 ;
255260 }
256261 return 0 ;
257262}
258263
259264int sh2lib_connect (struct sh2lib_config_t * cfg , struct sh2lib_handle * hd )
260265{
261- memset (hd , 0 , sizeof (* hd ));
262-
263- if (cfg == NULL ) {
264- ESP_LOGE (TAG , "[sh2-connect] pointer to sh2lib configurations cannot be NULL" );
265- goto error ;
266+ if (hd == NULL || cfg == NULL || cfg -> uri == NULL ) {
267+ ESP_LOGE (TAG , "[sh2-connect] Invalid argument" );
268+ return -1 ;
266269 }
267270
271+ memset (hd , 0 , sizeof (* hd ));
272+
268273 const char * proto [] = {"h2" , NULL };
269274 esp_tls_cfg_t tls_cfg = {
270275 .alpn_protos = proto ,
@@ -294,8 +299,19 @@ int sh2lib_connect(struct sh2lib_config_t *cfg, struct sh2lib_handle *hd)
294299
295300 struct http_parser_url u ;
296301 http_parser_url_init (& u );
297- http_parser_parse_url (cfg -> uri , strlen (cfg -> uri ), 0 , & u );
302+ if (http_parser_parse_url (cfg -> uri , strlen (cfg -> uri ), 0 , & u ) != 0 ) {
303+ ESP_LOGE (TAG , "[sh2-connect] Failed to parse URI" );
304+ goto error ;
305+ }
306+ if (!(u .field_set & (1 << UF_HOST ))) {
307+ ESP_LOGE (TAG , "[sh2-connect] Host field not present in URI" );
308+ goto error ;
309+ }
298310 hd -> hostname = strndup (& cfg -> uri [u .field_data [UF_HOST ].off ], u .field_data [UF_HOST ].len );
311+ if (!hd -> hostname ) {
312+ ESP_LOGE (TAG , "[sh2-connect] Failed to allocate memory for hostname" );
313+ goto error ;
314+ }
299315
300316 /* HTTP/2 Connection */
301317 if (do_http2_connect (hd ) != 0 ) {
@@ -311,6 +327,10 @@ int sh2lib_connect(struct sh2lib_config_t *cfg, struct sh2lib_handle *hd)
311327
312328void sh2lib_free (struct sh2lib_handle * hd )
313329{
330+ if (hd == NULL ) {
331+ return ;
332+ }
333+
314334 if (hd -> http2_sess ) {
315335 nghttp2_session_del (hd -> http2_sess );
316336 hd -> http2_sess = NULL ;
@@ -327,6 +347,11 @@ void sh2lib_free(struct sh2lib_handle *hd)
327347
328348int sh2lib_execute (struct sh2lib_handle * hd )
329349{
350+ if (hd == NULL ) {
351+ ESP_LOGE (TAG , "[sh2-execute] Invalid argument" );
352+ return -1 ;
353+ }
354+
330355 int ret ;
331356 ret = sh2lib_execute_send (hd );
332357 if (ret != 0 ) {
@@ -344,7 +369,7 @@ int sh2lib_execute(struct sh2lib_handle *hd)
344369int sh2lib_execute_recv (struct sh2lib_handle * hd )
345370{
346371 if (hd == NULL ) {
347- ESP_LOGE (TAG , "[sh2-execute-recv] pointer to sh2lib handle cannot be NULL " );
372+ ESP_LOGE (TAG , "[sh2-execute-recv] Invalid argument " );
348373 return -1 ;
349374 }
350375
@@ -359,7 +384,7 @@ int sh2lib_execute_recv(struct sh2lib_handle *hd)
359384int sh2lib_execute_send (struct sh2lib_handle * hd )
360385{
361386 if (hd == NULL ) {
362- ESP_LOGE (TAG , "[sh2-execute-recv] pointer to sh2lib handle cannot be NULL " );
387+ ESP_LOGE (TAG , "[sh2-execute-send] Invalid argument " );
363388 return -1 ;
364389 }
365390
@@ -373,6 +398,11 @@ int sh2lib_execute_send(struct sh2lib_handle *hd)
373398
374399int sh2lib_do_get_with_nv (struct sh2lib_handle * hd , const nghttp2_nv * nva , size_t nvlen , sh2lib_frame_data_recv_cb_t recv_cb )
375400{
401+ if (hd == NULL || (nva == NULL && nvlen > 0 )) {
402+ ESP_LOGE (TAG , "[sh2-do-get] Invalid argument" );
403+ return -1 ;
404+ }
405+
376406 int ret = nghttp2_submit_request (hd -> http2_sess , NULL , nva , nvlen , NULL , recv_cb );
377407 if (ret < 0 ) {
378408 ESP_LOGE (TAG , "[sh2-do-get] HEADERS call failed %i" , ret );
@@ -382,6 +412,11 @@ int sh2lib_do_get_with_nv(struct sh2lib_handle *hd, const nghttp2_nv *nva, size_
382412
383413int sh2lib_do_get (struct sh2lib_handle * hd , const char * path , sh2lib_frame_data_recv_cb_t recv_cb )
384414{
415+ if (hd == NULL || path == NULL || hd -> hostname == NULL ) {
416+ ESP_LOGE (TAG , "[sh2-do-get] Invalid argument" );
417+ return -1 ;
418+ }
419+
385420 const nghttp2_nv nva [] = { SH2LIB_MAKE_NV (":method" , "GET" ),
386421 SH2LIB_MAKE_NV (":scheme" , "https" ),
387422 SH2LIB_MAKE_NV (":authority" , hd -> hostname ),
@@ -403,6 +438,10 @@ int sh2lib_do_putpost_with_nv(struct sh2lib_handle *hd, const nghttp2_nv *nva, s
403438 sh2lib_putpost_data_cb_t send_cb ,
404439 sh2lib_frame_data_recv_cb_t recv_cb )
405440{
441+ if (hd == NULL || (nva == NULL && nvlen > 0 ) || send_cb == NULL ) {
442+ ESP_LOGE (TAG , "[sh2-do-putpost] Invalid argument" );
443+ return -1 ;
444+ }
406445
407446 nghttp2_data_provider sh2lib_data_provider ;
408447 sh2lib_data_provider .read_callback = sh2lib_data_provider_cb ;
@@ -418,6 +457,11 @@ int sh2lib_do_post(struct sh2lib_handle *hd, const char *path,
418457 sh2lib_putpost_data_cb_t send_cb ,
419458 sh2lib_frame_data_recv_cb_t recv_cb )
420459{
460+ if (hd == NULL || path == NULL || send_cb == NULL || hd -> hostname == NULL ) {
461+ ESP_LOGE (TAG , "[sh2-do-post] Invalid argument" );
462+ return -1 ;
463+ }
464+
421465 const nghttp2_nv nva [] = { SH2LIB_MAKE_NV (":method" , "POST" ),
422466 SH2LIB_MAKE_NV (":scheme" , "https" ),
423467 SH2LIB_MAKE_NV (":authority" , hd -> hostname ),
@@ -430,6 +474,11 @@ int sh2lib_do_put(struct sh2lib_handle *hd, const char *path,
430474 sh2lib_putpost_data_cb_t send_cb ,
431475 sh2lib_frame_data_recv_cb_t recv_cb )
432476{
477+ if (hd == NULL || path == NULL || send_cb == NULL || hd -> hostname == NULL ) {
478+ ESP_LOGE (TAG , "[sh2-do-put] Invalid argument" );
479+ return -1 ;
480+ }
481+
433482 const nghttp2_nv nva [] = { SH2LIB_MAKE_NV (":method" , "PUT" ),
434483 SH2LIB_MAKE_NV (":scheme" , "https" ),
435484 SH2LIB_MAKE_NV (":authority" , hd -> hostname ),
0 commit comments