fix: improvements allocation safety and string processing
This commit is contained in:
parent
f20d8f7115
commit
10d44e7ff5
5 changed files with 87 additions and 166 deletions
66
src/Config.c
66
src/Config.c
|
|
@ -3,6 +3,17 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static char *trim(char *value) {
|
||||
while (*value == ' ' || *value == '\t')
|
||||
value++;
|
||||
|
||||
char *end = value + strlen(value);
|
||||
while (end > value && (end[-1] == ' ' || end[-1] == '\t'))
|
||||
end--;
|
||||
*end = '\0';
|
||||
return value;
|
||||
}
|
||||
|
||||
int load_config(const char *filename, Config *config) {
|
||||
FILE *file = fopen(filename, "r");
|
||||
if (!file) {
|
||||
|
|
@ -33,51 +44,31 @@ int load_config(const char *filename, Config *config) {
|
|||
char *delimiter = strchr(line, '=');
|
||||
if (delimiter) {
|
||||
*delimiter = '\0';
|
||||
char *key = line;
|
||||
char *value = delimiter + 1;
|
||||
char *key = trim(line);
|
||||
char *value = trim(delimiter + 1);
|
||||
|
||||
while (*key == ' ' || *key == '\t')
|
||||
key++;
|
||||
while (*value == ' ' || *value == '\t')
|
||||
value++;
|
||||
|
||||
char *key_end = key + strlen(key) - 1;
|
||||
while (key_end > key && (*key_end == ' ' || *key_end == '\t')) {
|
||||
*key_end = '\0';
|
||||
key_end--;
|
||||
}
|
||||
|
||||
char *value_end = value + strlen(value) - 1;
|
||||
while (value_end > value && (*value_end == ' ' || *value_end == '\t' ||
|
||||
*value_end == '"' || *value_end == '\'')) {
|
||||
*value_end = '\0';
|
||||
value_end--;
|
||||
}
|
||||
|
||||
while (*value == ' ' || *value == '\t')
|
||||
value++;
|
||||
char *value_end = value + strlen(value);
|
||||
while (value_end > value &&
|
||||
(value_end[-1] == '"' || value_end[-1] == '\''))
|
||||
*--value_end = '\0';
|
||||
while (*value == '"' || *value == '\'')
|
||||
value++;
|
||||
|
||||
if (strcmp(section, "server") == 0) {
|
||||
if (strcmp(key, "host") == 0) {
|
||||
strncpy(config->host, value, sizeof(config->host) - 1);
|
||||
config->host[sizeof(config->host) - 1] = '\0';
|
||||
snprintf(config->host, sizeof(config->host), "%s", value);
|
||||
} else if (strcmp(key, "port") == 0) {
|
||||
config->port = atoi(value);
|
||||
} else if (strcmp(key, "locale") == 0) {
|
||||
strncpy(config->default_locale, value,
|
||||
sizeof(config->default_locale) - 1);
|
||||
config->default_locale[sizeof(config->default_locale) - 1] = '\0';
|
||||
snprintf(config->default_locale, sizeof(config->default_locale), "%s",
|
||||
value);
|
||||
}
|
||||
} else if (strcmp(section, "proxy") == 0) {
|
||||
if (strcmp(key, "proxy") == 0) {
|
||||
strncpy(config->proxy, value, sizeof(config->proxy) - 1);
|
||||
config->proxy[sizeof(config->proxy) - 1] = '\0';
|
||||
snprintf(config->proxy, sizeof(config->proxy), "%s", value);
|
||||
} else if (strcmp(key, "list_file") == 0) {
|
||||
strncpy(config->proxy_list_file, value,
|
||||
sizeof(config->proxy_list_file) - 1);
|
||||
config->proxy_list_file[sizeof(config->proxy_list_file) - 1] = '\0';
|
||||
snprintf(config->proxy_list_file, sizeof(config->proxy_list_file),
|
||||
"%s", value);
|
||||
} else if (strcmp(key, "max_retries") == 0) {
|
||||
config->max_proxy_retries = atoi(value);
|
||||
} else if (strcmp(key, "randomize_username") == 0) {
|
||||
|
|
@ -87,8 +78,7 @@ int load_config(const char *filename, Config *config) {
|
|||
}
|
||||
} else if (strcmp(section, "cache") == 0) {
|
||||
if (strcmp(key, "dir") == 0) {
|
||||
strncpy(config->cache_dir, value, sizeof(config->cache_dir) - 1);
|
||||
config->cache_dir[sizeof(config->cache_dir) - 1] = '\0';
|
||||
snprintf(config->cache_dir, sizeof(config->cache_dir), "%s", value);
|
||||
} else if (strcmp(key, "ttl_search") == 0) {
|
||||
config->cache_ttl_search = atoi(value);
|
||||
} else if (strcmp(key, "ttl_infobox") == 0) {
|
||||
|
|
@ -98,12 +88,10 @@ int load_config(const char *filename, Config *config) {
|
|||
}
|
||||
} else if (strcmp(section, "engines") == 0) {
|
||||
if (strcmp(key, "engines") == 0) {
|
||||
strncpy(config->engines, value, sizeof(config->engines) - 1);
|
||||
config->engines[sizeof(config->engines) - 1] = '\0';
|
||||
snprintf(config->engines, sizeof(config->engines), "%s", value);
|
||||
} else if (strcmp(key, "yacy_instance") == 0) {
|
||||
strncpy(config->yacy_instance, value,
|
||||
sizeof(config->yacy_instance) - 1);
|
||||
config->yacy_instance[sizeof(config->yacy_instance) - 1] = '\0';
|
||||
snprintf(config->yacy_instance, sizeof(config->yacy_instance), "%s",
|
||||
value);
|
||||
}
|
||||
} else if (strcmp(section, "rate_limit") == 0) {
|
||||
if (strcmp(key, "search_requests") == 0) {
|
||||
|
|
|
|||
|
|
@ -251,22 +251,20 @@ static void *infobox_thread_func(void *arg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int add_infobox_to_collection(InfoBox *infobox, char ****collection,
|
||||
int **inner_counts, int current_count) {
|
||||
static int add_infobox_to_collection(InfoBox *infobox,
|
||||
StringMatrix *collection) {
|
||||
const char *values[INFOBOX_FIELD_COUNT] = {
|
||||
infobox->title, infobox->thumbnail_url, infobox->extract,
|
||||
infobox->url, infobox->url,
|
||||
};
|
||||
return append_string_row(collection, inner_counts, current_count, values,
|
||||
INFOBOX_FIELD_COUNT);
|
||||
return string_matrix_append(collection, values, INFOBOX_FIELD_COUNT);
|
||||
}
|
||||
|
||||
static int add_warning_to_collection(const char *engine_name,
|
||||
const char *warning_message,
|
||||
char ****collection, int **inner_counts,
|
||||
int current_count) {
|
||||
StringMatrix *collection) {
|
||||
const char *values[] = {engine_name, warning_message};
|
||||
return append_string_row(collection, inner_counts, current_count, values, 2);
|
||||
return string_matrix_append(collection, values, 2);
|
||||
}
|
||||
|
||||
static void free_user_engine_list(char **user_engines, int user_engine_count) {
|
||||
|
|
@ -587,15 +585,14 @@ int results_handler(UrlParams *params) {
|
|||
}
|
||||
|
||||
if (filter_engine_count > 1) {
|
||||
char ***filter_matrix = NULL;
|
||||
int *filter_inner_counts = NULL;
|
||||
int filter_count = 0;
|
||||
StringMatrix filter_matrix;
|
||||
string_matrix_init(&filter_matrix);
|
||||
char *all_href = build_search_href(raw_query, "all", 1);
|
||||
|
||||
filter_count = add_link_to_collection(
|
||||
const char *all_values[LINK_FIELD_COUNT] = {
|
||||
all_href, "All",
|
||||
selected_engine ? "engine-filter" : "engine-filter active",
|
||||
&filter_matrix, &filter_inner_counts, filter_count);
|
||||
selected_engine ? "engine-filter" : "engine-filter active"};
|
||||
|
||||
string_matrix_append(&filter_matrix, all_values, LINK_FIELD_COUNT);
|
||||
free(all_href);
|
||||
|
||||
for (int i = 0; i < ENGINE_COUNT; i++) {
|
||||
|
|
@ -611,17 +608,18 @@ int results_handler(UrlParams *params) {
|
|||
? "engine-filter active"
|
||||
: "engine-filter";
|
||||
|
||||
filter_count = add_link_to_collection(
|
||||
filter_href, ENGINE_REGISTRY[i].name, filter_class, &filter_matrix,
|
||||
&filter_inner_counts, filter_count);
|
||||
const char *filter_values[LINK_FIELD_COUNT] = {
|
||||
filter_href, ENGINE_REGISTRY[i].name, filter_class};
|
||||
string_matrix_append(&filter_matrix, filter_values, LINK_FIELD_COUNT);
|
||||
free(filter_href);
|
||||
}
|
||||
|
||||
if (filter_count > 0) {
|
||||
context_set_array_of_arrays(&ctx, "engine_filters", filter_matrix,
|
||||
filter_count, filter_inner_counts);
|
||||
free_string_matrix(filter_matrix, filter_inner_counts, filter_count);
|
||||
if (filter_matrix.count > 0) {
|
||||
context_set_array_of_arrays(&ctx, "engine_filters", filter_matrix.rows,
|
||||
filter_matrix.count,
|
||||
filter_matrix.field_counts);
|
||||
}
|
||||
string_matrix_free(&filter_matrix);
|
||||
}
|
||||
|
||||
if (page == 1) {
|
||||
|
|
@ -673,25 +671,23 @@ int results_handler(UrlParams *params) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
char ***infobox_matrix = NULL;
|
||||
int *infobox_inner_counts = NULL;
|
||||
int infobox_count = 0;
|
||||
StringMatrix infobox_matrix;
|
||||
string_matrix_init(&infobox_matrix);
|
||||
|
||||
if (page == 1) {
|
||||
for (int i = 0; i < HANDLER_COUNT; i++) {
|
||||
if (infobox_data[i].success) {
|
||||
infobox_count =
|
||||
add_infobox_to_collection(&infobox_data[i].result, &infobox_matrix,
|
||||
&infobox_inner_counts, infobox_count);
|
||||
add_infobox_to_collection(&infobox_data[i].result, &infobox_matrix);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (infobox_count > 0) {
|
||||
context_set_array_of_arrays(&ctx, "infoboxes", infobox_matrix,
|
||||
infobox_count, infobox_inner_counts);
|
||||
free_string_matrix(infobox_matrix, infobox_inner_counts, infobox_count);
|
||||
if (infobox_matrix.count > 0) {
|
||||
context_set_array_of_arrays(&ctx, "infoboxes", infobox_matrix.rows,
|
||||
infobox_matrix.count,
|
||||
infobox_matrix.field_counts);
|
||||
}
|
||||
string_matrix_free(&infobox_matrix);
|
||||
|
||||
int warning_count = 0;
|
||||
for (int i = 0; i < enabled_engine_count; i++) {
|
||||
|
|
@ -700,26 +696,25 @@ int results_handler(UrlParams *params) {
|
|||
}
|
||||
|
||||
if (warning_count > 0) {
|
||||
char ***warning_matrix = NULL;
|
||||
int *warning_inner_counts = NULL;
|
||||
int warning_index = 0;
|
||||
StringMatrix warning_matrix;
|
||||
string_matrix_init(&warning_matrix);
|
||||
|
||||
for (int i = 0; i < enabled_engine_count; i++) {
|
||||
const char *warning_message = warning_message_for_job(&jobs[i], locale);
|
||||
if (!warning_message)
|
||||
continue;
|
||||
|
||||
warning_index = add_warning_to_collection(
|
||||
jobs[i].engine->name, warning_message, &warning_matrix,
|
||||
&warning_inner_counts, warning_index);
|
||||
add_warning_to_collection(jobs[i].engine->name, warning_message,
|
||||
&warning_matrix);
|
||||
}
|
||||
|
||||
if (warning_index > 0) {
|
||||
context_set_array_of_arrays(&ctx, "engine_warnings", warning_matrix,
|
||||
warning_index, warning_inner_counts);
|
||||
if (warning_matrix.count > 0) {
|
||||
context_set_array_of_arrays(&ctx, "engine_warnings", warning_matrix.rows,
|
||||
warning_matrix.count,
|
||||
warning_matrix.field_counts);
|
||||
}
|
||||
|
||||
free_string_matrix(warning_matrix, warning_inner_counts, warning_index);
|
||||
string_matrix_free(&warning_matrix);
|
||||
}
|
||||
|
||||
int total_results = 0;
|
||||
|
|
|
|||
|
|
@ -214,13 +214,17 @@ int setup_job(ScrapeJob *job, CURLM *multi_handle) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
for (char *p = encoded_query + strlen(encoded_query) - 3; p >= encoded_query;
|
||||
p--) {
|
||||
if (p[0] == '%' && p[1] == '2' && p[2] == '0') {
|
||||
*p = '+';
|
||||
memmove(p + 1, p + 3, strlen(p + 3) + 1);
|
||||
char *read = encoded_query;
|
||||
char *write = encoded_query;
|
||||
while (*read) {
|
||||
if (read[0] == '%' && read[1] == '2' && read[2] == '0') {
|
||||
*write++ = '+';
|
||||
read += 3;
|
||||
} else {
|
||||
*write++ = *read++;
|
||||
}
|
||||
}
|
||||
*write = '\0';
|
||||
|
||||
char *full_url =
|
||||
build_search_url(job->engine->base_url, job->engine->page_param,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ static int themes_initialized = 0;
|
|||
void init_themes(const char *static_path) {
|
||||
if (themes_initialized)
|
||||
return;
|
||||
themes_initialized = 1;
|
||||
|
||||
char themes_dir[512];
|
||||
snprintf(themes_dir, sizeof(themes_dir), "%s/themes", static_path);
|
||||
|
|
@ -26,20 +25,32 @@ void init_themes(const char *static_path) {
|
|||
struct dirent *entry;
|
||||
int capacity = 4;
|
||||
themes_list = malloc(sizeof(char *) * capacity);
|
||||
if (!themes_list) {
|
||||
closedir(dir);
|
||||
return;
|
||||
}
|
||||
themes_count = 0;
|
||||
|
||||
while ((entry = readdir(dir)) != NULL) {
|
||||
size_t len = strlen(entry->d_name);
|
||||
if (len > 4 && strcmp(entry->d_name + len - 4, ".css") == 0) {
|
||||
if (themes_count >= capacity) {
|
||||
capacity *= 2;
|
||||
themes_list = realloc(themes_list, sizeof(char *) * capacity);
|
||||
int new_capacity = capacity * 2;
|
||||
char **new_list = realloc(themes_list, sizeof(char *) * new_capacity);
|
||||
if (!new_list)
|
||||
break;
|
||||
themes_list = new_list;
|
||||
capacity = new_capacity;
|
||||
}
|
||||
themes_list[themes_count] = strndup(entry->d_name, len - 4);
|
||||
char *theme = strndup(entry->d_name, len - 4);
|
||||
if (!theme)
|
||||
break;
|
||||
themes_list[themes_count] = theme;
|
||||
themes_count++;
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
themes_initialized = 1;
|
||||
|
||||
for (int i = 0; i < themes_count; i++) {
|
||||
for (int j = i + 1; j < themes_count; j++) {
|
||||
|
|
@ -206,50 +217,6 @@ int user_engines_contains(const char *engine_id, char **ids, int count) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int append_string_row(char ****matrix, int **inner_counts, int row_count,
|
||||
const char *const *values, int field_count) {
|
||||
if (!matrix || !inner_counts || !values || field_count <= 0)
|
||||
return row_count;
|
||||
|
||||
char **row = calloc((size_t)field_count, sizeof(*row));
|
||||
if (!row)
|
||||
return row_count;
|
||||
|
||||
for (int i = 0; i < field_count; i++) {
|
||||
row[i] = strdup(values[i] ? values[i] : "");
|
||||
if (!row[i]) {
|
||||
for (int j = 0; j < i; j++)
|
||||
free(row[j]);
|
||||
free(row);
|
||||
return row_count;
|
||||
}
|
||||
}
|
||||
|
||||
char ***new_matrix = malloc(sizeof(*new_matrix) * (row_count + 1));
|
||||
int *new_counts = malloc(sizeof(*new_counts) * (row_count + 1));
|
||||
if (!new_matrix || !new_counts) {
|
||||
free(new_matrix);
|
||||
free(new_counts);
|
||||
for (int i = 0; i < field_count; i++)
|
||||
free(row[i]);
|
||||
free(row);
|
||||
return row_count;
|
||||
}
|
||||
|
||||
if (row_count > 0) {
|
||||
memcpy(new_matrix, *matrix, sizeof(*new_matrix) * row_count);
|
||||
memcpy(new_counts, *inner_counts, sizeof(*new_counts) * row_count);
|
||||
}
|
||||
|
||||
new_matrix[row_count] = row;
|
||||
new_counts[row_count] = field_count;
|
||||
free(*matrix);
|
||||
free(*inner_counts);
|
||||
*matrix = new_matrix;
|
||||
*inner_counts = new_counts;
|
||||
return row_count + 1;
|
||||
}
|
||||
|
||||
void free_string_matrix(char ***matrix, int *inner_counts, int row_count) {
|
||||
if (matrix) {
|
||||
for (int i = 0; i < row_count; i++) {
|
||||
|
|
@ -324,31 +291,6 @@ void string_matrix_free(StringMatrix *matrix) {
|
|||
*matrix = (StringMatrix){0};
|
||||
}
|
||||
|
||||
int add_link_to_collection(const char *href, const char *label,
|
||||
const char *class_name, char ****collection,
|
||||
int **inner_counts, int current_count) {
|
||||
const char *values[LINK_FIELD_COUNT] = {href, label, class_name};
|
||||
return append_string_row(collection, inner_counts, current_count, values,
|
||||
LINK_FIELD_COUNT);
|
||||
}
|
||||
|
||||
int build_pagination(int page, char *(*href_builder)(int page, void *data),
|
||||
void *data, char ****out_matrix, int **out_inner_counts) {
|
||||
if (!out_matrix || !out_inner_counts)
|
||||
return 0;
|
||||
|
||||
StringMatrix matrix;
|
||||
if (string_matrix_build_pagination(page, href_builder, data, &matrix) != 0) {
|
||||
*out_matrix = NULL;
|
||||
*out_inner_counts = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*out_matrix = matrix.rows;
|
||||
*out_inner_counts = matrix.field_counts;
|
||||
return matrix.count;
|
||||
}
|
||||
|
||||
int string_matrix_build_pagination(int page,
|
||||
char *(*href_builder)(int page, void *data),
|
||||
void *data, StringMatrix *out_matrix) {
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@ int is_engine_id_enabled(const char *engine_id);
|
|||
int get_user_engines(char ***out_ids, int *out_count);
|
||||
int user_engines_contains(const char *engine_id, char **ids, int count);
|
||||
|
||||
int append_string_row(char ****matrix, int **inner_counts, int row_count,
|
||||
const char *const *values, int field_count);
|
||||
void free_string_matrix(char ***matrix, int *inner_counts, int row_count);
|
||||
|
||||
void string_matrix_init(StringMatrix *matrix);
|
||||
|
|
@ -40,12 +38,6 @@ int string_matrix_append(StringMatrix *matrix, const char *const *values,
|
|||
int field_count);
|
||||
void string_matrix_free(StringMatrix *matrix);
|
||||
|
||||
int add_link_to_collection(const char *href, const char *label,
|
||||
const char *class_name, char ****collection,
|
||||
int **inner_counts, int current_count);
|
||||
|
||||
int build_pagination(int page, char *(*href_builder)(int page, void *data),
|
||||
void *data, char ****out_matrix, int **out_inner_counts);
|
||||
int string_matrix_build_pagination(int page,
|
||||
char *(*href_builder)(int page, void *data),
|
||||
void *data, StringMatrix *out_matrix);
|
||||
|
|
|
|||
Loading…
Reference in a new issue