Skip to content

Commit

Permalink
Fix leaks in cstest.
Browse files Browse the repository at this point in the history
- Rewrite split to remove leaks and improve runtime by 6%
- Add free()
  • Loading branch information
Rot127 committed Apr 20, 2024
1 parent 517f0d5 commit bf8ee12
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 27 deletions.
2 changes: 1 addition & 1 deletion suite/cstest/include/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#define X86_32 1
#define X86_64 2

char **split(char *str, char *delim, int *size);
char **split(char *str, const char *delim, int *size);
void print_strs(char **list_str, int size);
void free_strs(char **list_str, int size);
void add_str(char **src, const char *format, ...);
Expand Down
3 changes: 2 additions & 1 deletion suite/cstest/src/capstone_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ void test_single_issue(csh *handle, cs_mode mode, char *line, int detail)
}

count = cs_disasm(*handle, code, size_byte, offset, 0, &insn);
free_strs(list_byte, size_byte);
free(code);
for (i = 0; i < count; ++i) {
tmp = (char *)malloc(strlen(insn[i].mnemonic) + strlen(insn[i].op_str) + 100);
strcpy(tmp, insn[i].mnemonic);
Expand Down Expand Up @@ -295,7 +297,6 @@ void test_single_issue(csh *handle, cs_mode mode, char *line, int detail)

cs_free(insn, count);
free_strs(list_part, size_part);
free_strs(list_byte, size_byte);
free(cs_result);
// free_strs(list_part_cs_result, size_part_cs_result);
free_strs(list_part_issue_result, size_part_issue_result);
Expand Down
60 changes: 35 additions & 25 deletions suite/cstest/src/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,44 @@


#include "helper.h"

char **split(char *str, char *delim, int *size)
{
char **result;
char *token, *src;
int cnt;

cnt = 0;
src = str;
result = NULL;

while ((token = strstr(src, delim)) != NULL) {
result = (char **)realloc(result, sizeof(char *) * (cnt + 1));
result[cnt] = (char *)calloc(1, sizeof(char) * (int)(token - src + 10));
memcpy(result[cnt], src, token - src);
result[cnt][token - src] = '\0';
src = token + strlen(delim);
cnt ++;
#include <string.h>

/// Splits a string into a list of strings, separated by the given delimeter.
/// The last element in the list is always a duplicate of @str.
/// @str is not freed.
/// The number of elements in the list is written to @size
char **split(char *str, const char *delim, int *size) {
// Count the number of delimeters in the string
uint32_t elem_cnt = 0;
uint32_t delim_len = strlen(delim);
char *split_at = NULL;
char *str_iter = str;
// Count delimeters
while ((split_at = strstr(str_iter, delim)) != NULL) {
str_iter = split_at + delim_len;
if (split_at != str && split_at == str + strlen(str) - delim_len) {
// Don't increment if the delimeter is at the very beginning or end of the string.
elem_cnt++;
}
}

if (strlen(src) > 0) {
result = (char **)realloc(result, sizeof(char *) * (cnt + 1));
result[cnt] = strdup(src);
cnt ++;
uint32_t table_size = elem_cnt + 2; // Last element is the whole string

char **list = calloc(table_size, sizeof(char*));
uint32_t count = 0;
while ((split_at = strstr(str_iter, delim)) != NULL) {
unsigned sub_len = (split_at - str_iter);
list[count] = calloc(sub_len + 1, sizeof(char));
memcpy(list[count], str_iter, sub_len);
count++;
str_iter += sub_len + strlen(delim);
}

*size = cnt;
return result;
if (strlen(str) > 0) {
list[count] = strdup(str);
count++;
}
*size = count;
return list;
}

void print_strs(char **list_str, int size)
Expand Down

0 comments on commit bf8ee12

Please sign in to comment.