Skip to content

Commit 3652e38

Browse files
authored
Fix memory leaks found by valgrind (#64)
* Fixed PHP lint errors. Signed-off-by: asafpamzn <[email protected]>
1 parent 3f1bab8 commit 3652e38

File tree

2 files changed

+59
-43
lines changed

2 files changed

+59
-43
lines changed

valkey_glide_hash_common.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,12 +1107,13 @@ int process_h_mget_result(CommandResponse* response, void* output, zval* return_
11071107
efree(args);
11081108
return 0;
11091109
}
1110-
/* Initialize return array */
1111-
array_init(return_value);
1110+
11121111

11131112
/* Process the result - map back to original field names */
11141113
int ret_val = 0;
11151114
if (response && response->response_type == Array) {
1115+
/* Initialize return array */
1116+
array_init(return_value);
11161117
for (int i = 0; i < args->field_count && i < response->array_value_len; i++) {
11171118
zval* field = &args->fields[i];
11181119
zval field_value;
@@ -1146,6 +1147,8 @@ int process_h_mget_result(CommandResponse* response, void* output, zval* return_
11461147
}
11471148
}
11481149
ret_val = 1;
1150+
} else {
1151+
ZVAL_NULL(return_value);
11491152
}
11501153

11511154
/* Free field array */

valkey_glide_s_common.c

Lines changed: 54 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ int process_s_bool_result_async(CommandResponse* response, void* output, zval* r
528528
*/
529529
int process_s_set_result_async(CommandResponse* response, void* output, zval* return_value) {
530530
if (!response) {
531-
array_init(return_value);
531+
ZVAL_NULL(return_value);
532532
return 0;
533533
}
534534

@@ -539,8 +539,7 @@ int process_s_set_result_async(CommandResponse* response, void* output, zval* re
539539
return command_response_to_zval(
540540
response, return_value, COMMAND_RESPONSE_NOT_ASSOSIATIVE, false);
541541
}
542-
543-
array_init(return_value);
542+
ZVAL_NULL(return_value);
544543
return 0;
545544
}
546545

@@ -573,27 +572,27 @@ int process_s_scan_result_async(CommandResponse* response, void* output, zval* r
573572

574573
if (!response) {
575574
if (args->scan_iter) {
576-
ZVAL_STRING(args->scan_iter, "0");
575+
ZVAL_STRINGL(args->scan_iter, "0", 1);
577576
efree(args->cursor);
578577
efree(args);
579578
} else {
580579
printf("No response received in process_s_scan_result_async\n");
581580
args->cursor = "0";
582581
}
583582

584-
array_init(return_value);
583+
ZVAL_NULL(return_value);
585584
return 0;
586585
}
587586

588587
if (response->response_type != Array || response->array_value_len < 2) {
589588
if (args->scan_iter) {
590-
ZVAL_STRING(args->scan_iter, "0");
589+
ZVAL_STRINGL(args->scan_iter, "0", 1);
591590
efree(args->cursor);
592591
efree(args);
593592
} else {
594593
args->cursor = "0";
595594
}
596-
array_init(return_value);
595+
ZVAL_NULL(return_value);
597596

598597
return 0;
599598
}
@@ -607,13 +606,13 @@ int process_s_scan_result_async(CommandResponse* response, void* output, zval* r
607606
/* Handle unexpected cursor type */
608607

609608
if (args->scan_iter) {
610-
ZVAL_STRING(args->scan_iter, "0");
609+
ZVAL_STRINGL(args->scan_iter, "0", 1);
611610
efree(args->cursor);
612611
efree(args);
613612
} else {
614613
args->cursor = "0";
615614
}
616-
array_init(return_value);
615+
ZVAL_NULL(return_value);
617616
return 0;
618617
}
619618

@@ -622,7 +621,7 @@ int process_s_scan_result_async(CommandResponse* response, void* output, zval* r
622621
if (elements_resp->response_type != Array) {
623622
array_init(return_value);
624623
if (args->scan_iter) {
625-
ZVAL_STRING(args->scan_iter, "0");
624+
ZVAL_STRINGL(args->scan_iter, "0", 1);
626625
efree(args->cursor);
627626
efree(args);
628627
} else {
@@ -633,14 +632,6 @@ int process_s_scan_result_async(CommandResponse* response, void* output, zval* r
633632
}
634633
/* Handle scan completion: when server returns cursor="0", scan is complete */
635634
if (cursor_resp->string_value_len == 1 && cursor_resp->string_value[0] == '0') {
636-
/* Free old cursor and keep it as "0" to indicate completion */
637-
if (args->cursor) {
638-
efree(args->cursor);
639-
}
640-
args->cursor = emalloc(2);
641-
strcpy(args->cursor, "0");
642-
643-
644635
/* If there are elements in this final batch, return them using robust conversion */
645636
if (elements_resp->array_value_len > 0) {
646637
status = command_response_to_zval(elements_resp,
@@ -650,9 +641,17 @@ int process_s_scan_result_async(CommandResponse* response, void* output, zval* r
650641
: COMMAND_RESPONSE_NOT_ASSOSIATIVE,
651642
false);
652643
if (args->scan_iter) {
653-
ZVAL_STRING(args->scan_iter, args->cursor);
644+
zval_ptr_dtor(args->scan_iter);
645+
ZVAL_STRINGL(args->scan_iter, "0", 1);
654646
efree(args->cursor);
655647
efree(args);
648+
} else {
649+
/* Free old cursor and keep it as "0" to indicate completion */
650+
if (args->cursor) {
651+
efree(args->cursor);
652+
}
653+
args->cursor = emalloc(2);
654+
strcpy(args->cursor, "0");
656655
}
657656

658657
return status;
@@ -661,42 +660,56 @@ int process_s_scan_result_async(CommandResponse* response, void* output, zval* r
661660
/* No elements in final batch - return FALSE to terminate loop */
662661
array_init(return_value);
663662
if (args->scan_iter) {
664-
ZVAL_STRING(args->scan_iter, "0");
663+
zval_ptr_dtor(args->scan_iter);
664+
ZVAL_STRINGL(args->scan_iter, "0", 1);
665665
efree(args->cursor);
666666
efree(args);
667667
} else {
668-
args->cursor = "0";
668+
/* Free old cursor and keep it as "0" to indicate completion */
669+
if (args->cursor) {
670+
efree(args->cursor);
671+
}
672+
args->cursor = emalloc(2);
673+
strcpy(args->cursor, "0");
669674
}
670675

671676
return 1;
672677
}
673678
}
674679

675680
/* Normal case: cursor != "0", update cursor string and return elements array */
676-
if (args->cursor) {
677-
efree(args->cursor);
678-
}
679-
680-
/* Use length-controlled string copying to prevent reading beyond string boundary */
681-
size_t cursor_len = cursor_resp->string_value_len;
682-
args->cursor = emalloc(cursor_len + 1);
683-
memcpy(args->cursor, new_cursor_str, cursor_len);
684-
(args->cursor)[cursor_len] = '\0';
685-
686-
687-
/* Use command_response_to_zval for robust element processing */
688-
status = command_response_to_zval(elements_resp,
689-
return_value,
690-
(args->cmd_type == HScan || args->cmd_type == ZScan)
691-
? COMMAND_RESPONSE_SCAN_ASSOSIATIVE_ARRAY
692-
: COMMAND_RESPONSE_NOT_ASSOSIATIVE,
693-
false);
694681
if (args->scan_iter) {
695-
ZVAL_STRING(args->scan_iter, args->cursor);
682+
/* For scan_iter mode, we'll update the zval directly and free everything */
683+
status = command_response_to_zval(elements_resp,
684+
return_value,
685+
(args->cmd_type == HScan || args->cmd_type == ZScan)
686+
? COMMAND_RESPONSE_SCAN_ASSOSIATIVE_ARRAY
687+
: COMMAND_RESPONSE_NOT_ASSOSIATIVE,
688+
false);
689+
zval_ptr_dtor(args->scan_iter);
690+
ZVAL_STRINGL(args->scan_iter, new_cursor_str, cursor_resp->string_value_len);
696691
efree(args->cursor);
697692
efree(args);
698-
}
693+
} else {
694+
/* For non-scan_iter mode, update the cursor pointer */
695+
if (args->cursor) {
696+
efree(args->cursor);
697+
}
698+
699+
/* Use length-controlled string copying to prevent reading beyond string boundary */
700+
size_t cursor_len = cursor_resp->string_value_len;
701+
args->cursor = emalloc(cursor_len + 1);
702+
memcpy(args->cursor, new_cursor_str, cursor_len);
703+
(args->cursor)[cursor_len] = '\0';
699704

705+
/* Use command_response_to_zval for robust element processing */
706+
status = command_response_to_zval(elements_resp,
707+
return_value,
708+
(args->cmd_type == HScan || args->cmd_type == ZScan)
709+
? COMMAND_RESPONSE_SCAN_ASSOSIATIVE_ARRAY
710+
: COMMAND_RESPONSE_NOT_ASSOSIATIVE,
711+
false);
712+
}
700713

701714
return status;
702715
}

0 commit comments

Comments
 (0)