@@ -141,6 +141,7 @@ char * STRATUM_V1_receive_jsonrpc_line(esp_transport_handle_t transport)
141141 char * line = NULL ;
142142 char recv_buffer [BUFFER_SIZE ];
143143 int nbytes ;
144+ int timeout_count = 0 ;
144145
145146 while (!strstr (json_rpc_buffer , "\n" )) {
146147 memset (recv_buffer , 0 , BUFFER_SIZE );
@@ -168,10 +169,17 @@ char * STRATUM_V1_receive_jsonrpc_line(esp_transport_handle_t transport)
168169 }
169170 return NULL ;
170171 }
171- if (nbytes > 0 ) {
172- realloc_json_buffer (nbytes );
173- strncat (json_rpc_buffer , recv_buffer , nbytes );
172+ if (nbytes == 0 ) {
173+ timeout_count ++ ;
174+ if (timeout_count >= 10 ) {
175+ ESP_LOGW (TAG , "Transport read timed out %d times, giving up" , timeout_count );
176+ return NULL ;
177+ }
178+ continue ;
174179 }
180+ timeout_count = 0 ;
181+ realloc_json_buffer (nbytes );
182+ strncat (json_rpc_buffer , recv_buffer , nbytes );
175183 }
176184
177185 // Extract the line
@@ -370,7 +378,18 @@ void STRATUM_V1_parse(StratumApiV1Message * message, const char * stratum_json)
370378 }
371379 new_work -> merkle_branches = malloc (HASH_SIZE * new_work -> n_merkle_branches );
372380 for (size_t i = 0 ; i < new_work -> n_merkle_branches ; i ++ ) {
373- hex2bin (cJSON_GetArrayItem (merkle_branch , i )-> valuestring , new_work -> merkle_branches + HASH_SIZE * i , HASH_SIZE );
381+ cJSON * branch = cJSON_GetArrayItem (merkle_branch , i );
382+ if (!branch || !cJSON_IsString (branch )) {
383+ ESP_LOGE (TAG , "Invalid merkle branch element at index %d" , (int )i );
384+ free (new_work -> merkle_branches );
385+ free (new_work -> job_id );
386+ free (new_work -> prev_block_hash );
387+ free (new_work -> coinbase_1 );
388+ free (new_work -> coinbase_2 );
389+ free (new_work );
390+ goto done ;
391+ }
392+ hex2bin (branch -> valuestring , new_work -> merkle_branches + HASH_SIZE * i , HASH_SIZE );
374393 }
375394
376395 new_work -> version = strtoul (cJSON_GetArrayItem (params , 5 )-> valuestring , NULL , 16 );
@@ -384,16 +403,32 @@ void STRATUM_V1_parse(StratumApiV1Message * message, const char * stratum_json)
384403 message -> mining_notification = new_work ;
385404 } else if (message -> method == MINING_SET_DIFFICULTY ) {
386405 cJSON * params = cJSON_GetObjectItem (json , "params" );
387- uint32_t difficulty = cJSON_GetArrayItem (params , 0 )-> valueint ;
406+ cJSON * p0 = params ? cJSON_GetArrayItem (params , 0 ) : NULL ;
407+ if (p0 == NULL ) {
408+ ESP_LOGE (TAG , "Invalid params in mining.set_difficulty" );
409+ goto done ;
410+ }
411+ uint32_t difficulty = p0 -> valueint ;
388412 message -> new_difficulty = difficulty ;
389413 } else if (message -> method == MINING_SET_VERSION_MASK ) {
390414 cJSON * params = cJSON_GetObjectItem (json , "params" );
391- uint32_t version_mask = strtoul (cJSON_GetArrayItem (params , 0 )-> valuestring , NULL , 16 );
415+ cJSON * p0 = params ? cJSON_GetArrayItem (params , 0 ) : NULL ;
416+ if (p0 == NULL || !cJSON_IsString (p0 )) {
417+ ESP_LOGE (TAG , "Invalid params in mining.set_version_mask" );
418+ goto done ;
419+ }
420+ uint32_t version_mask = strtoul (p0 -> valuestring , NULL , 16 );
392421 message -> version_mask = version_mask ;
393422 } else if (message -> method == MINING_SET_EXTRANONCE ) {
394423 cJSON * params = cJSON_GetObjectItem (json , "params" );
395- char * extranonce_str = cJSON_GetArrayItem (params , 0 )-> valuestring ;
396- uint32_t extranonce_2_len = cJSON_GetArrayItem (params , 1 )-> valueint ;
424+ cJSON * p0 = params ? cJSON_GetArrayItem (params , 0 ) : NULL ;
425+ cJSON * p1 = params ? cJSON_GetArrayItem (params , 1 ) : NULL ;
426+ if (p0 == NULL || !cJSON_IsString (p0 ) || p1 == NULL ) {
427+ ESP_LOGE (TAG , "Invalid params in mining.set_extranonce" );
428+ goto done ;
429+ }
430+ char * extranonce_str = p0 -> valuestring ;
431+ uint32_t extranonce_2_len = p1 -> valueint ;
397432 if (extranonce_2_len > MAX_EXTRANONCE_2_LEN ) {
398433 ESP_LOGW (TAG , "Extranonce_2_len %u exceeds maximum %d, clamping to maximum" ,
399434 extranonce_2_len , MAX_EXTRANONCE_2_LEN );
0 commit comments