Skip to content

Commit d19656d

Browse files
committed
fix: logic bug in error categorization
- add safer string handling for input paths - add cleanup helper for partially allocated cache arrays in autocomplete
1 parent 2e7784a commit d19656d

7 files changed

Lines changed: 53 additions & 16 deletions

File tree

src/autocomplete.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
#define CACHE_TTL_SECONDS 3600
44
#define PACKAGE_CACHE_FILE "packages.cache"
55

6+
static void free_command_cache(char **commands, int count) {
7+
if (!commands) {
8+
return;
9+
}
10+
11+
for (int i = 0; i < count; i++) {
12+
free(commands[i]);
13+
}
14+
free(commands);
15+
}
16+
617
static int is_cache_valid(const char *cache_path) {
718
struct stat cache_stat;
819
if (stat(cache_path, &cache_stat) != 0) {
@@ -35,12 +46,16 @@ static void load_cache_from_file(const char *cache_path) {
3546
char **new_commands =
3647
realloc(cached_commands, sizeof(char *) * (command_count + 1));
3748
if (!new_commands) {
49+
free_command_cache(cached_commands, command_count - 1);
50+
cached_commands = NULL;
3851
fclose(fp);
3952
return;
4053
}
4154
cached_commands = new_commands;
4255
cached_commands[command_count - 1] = strdup(line);
4356
if (!cached_commands[command_count - 1]) {
57+
free_command_cache(cached_commands, command_count - 1);
58+
cached_commands = NULL;
4459
fclose(fp);
4560
return;
4661
}
@@ -54,11 +69,15 @@ static void load_cache_from_file(const char *cache_path) {
5469
char **new_commands =
5570
realloc(cached_commands, sizeof(char *) * (command_count + 1));
5671
if (!new_commands) {
72+
free_command_cache(cached_commands, command_count - 1);
73+
cached_commands = NULL;
5774
return;
5875
}
5976
cached_commands = new_commands;
6077
cached_commands[command_count - 1] = strdup(custom_cmds[i]);
6178
if (!cached_commands[command_count - 1]) {
79+
free_command_cache(cached_commands, command_count - 1);
80+
cached_commands = NULL;
6281
return;
6382
}
6483
}
@@ -145,12 +164,16 @@ void cache_pacman_commands(void) {
145164
char **new_commands =
146165
realloc(cached_commands, sizeof(char *) * (command_count + 1));
147166
if (!new_commands) {
167+
free_command_cache(cached_commands, command_count - 1);
168+
cached_commands = NULL;
148169
pclose(fp);
149170
return;
150171
}
151172
cached_commands = new_commands;
152173
cached_commands[command_count - 1] = strdup(path);
153174
if (!cached_commands[command_count - 1]) {
175+
free_command_cache(cached_commands, command_count - 1);
176+
cached_commands = NULL;
154177
pclose(fp);
155178
return;
156179
}
@@ -164,11 +187,15 @@ void cache_pacman_commands(void) {
164187
char **new_commands =
165188
realloc(cached_commands, sizeof(char *) * (command_count + 1));
166189
if (!new_commands) {
190+
free_command_cache(cached_commands, command_count - 1);
191+
cached_commands = NULL;
167192
return;
168193
}
169194
cached_commands = new_commands;
170195
cached_commands[command_count - 1] = strdup(custom_cmds[i]);
171196
if (!cached_commands[command_count - 1]) {
197+
free_command_cache(cached_commands, command_count - 1);
198+
cached_commands = NULL;
172199
return;
173200
}
174201
}

src/commands.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ static void execute_command(const char *command, const char *log_message) {
116116

117117
static void get_user_input(char *buffer, const char *prompt) {
118118
rl_attempted_completion_function = command_completion;
119-
get_input(buffer, prompt);
119+
get_input(buffer, MAX_INPUT_LENGTH, prompt);
120120
rl_attempted_completion_function = NULL;
121121
}
122122

src/error_handling.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,25 +196,25 @@ void archium_error_add_details(ArchiumErrorContext *ctx, const char *details,
196196
}
197197

198198
const char *archium_error_get_category(ArchiumError error_code) {
199-
if (error_code >= ARCHIUM_ERROR_INVALID_INPUT &&
199+
if (error_code <= ARCHIUM_ERROR_INVALID_INPUT &&
200200
error_code >= ARCHIUM_ERROR_BUFFER_OVERFLOW) {
201201
return "Input/Validation";
202-
} else if (error_code >= ARCHIUM_ERROR_SYSTEM_CALL &&
202+
} else if (error_code <= ARCHIUM_ERROR_SYSTEM_CALL &&
203203
error_code >= ARCHIUM_ERROR_PROCESS_FAILED) {
204204
return "System";
205-
} else if (error_code >= ARCHIUM_ERROR_PACKAGE_MANAGER &&
205+
} else if (error_code <= ARCHIUM_ERROR_PACKAGE_MANAGER &&
206206
error_code >= ARCHIUM_ERROR_PACKAGE_DEPENDENCY) {
207207
return "Package Management";
208-
} else if (error_code >= ARCHIUM_ERROR_NETWORK &&
208+
} else if (error_code <= ARCHIUM_ERROR_NETWORK &&
209209
error_code >= ARCHIUM_ERROR_CONNECTION_TIMEOUT) {
210210
return "Network";
211-
} else if (error_code >= ARCHIUM_ERROR_PERMISSION &&
211+
} else if (error_code <= ARCHIUM_ERROR_PERMISSION &&
212212
error_code >= ARCHIUM_ERROR_ACCESS_DENIED) {
213213
return "Permission/Security";
214-
} else if (error_code >= ARCHIUM_ERROR_CONFIG &&
214+
} else if (error_code <= ARCHIUM_ERROR_CONFIG &&
215215
error_code >= ARCHIUM_ERROR_CONFIG_MISSING) {
216216
return "Configuration";
217-
} else if (error_code >= ARCHIUM_ERROR_PLUGIN &&
217+
} else if (error_code <= ARCHIUM_ERROR_PLUGIN &&
218218
error_code >= ARCHIUM_ERROR_PLUGIN_INVALID) {
219219
return "Plugin";
220220
}

src/include/commands.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
#ifndef COMMANDS_H
22
#define COMMANDS_H
33

4+
#include <stddef.h>
5+
46
#include "config.h"
57
#include "error.h"
68

79
ArchiumError handle_exec_command(const char *command,
810
const char *package_manager);
911
ArchiumError handle_command(const char *input, const char *package_manager);
10-
void get_input(char *input, const char *prompt);
12+
void get_input(char *input, size_t input_size, const char *prompt);
1113
int is_valid_command(const char *command);
1214
int check_archium_file(void);
1315
void install_git(void);
@@ -16,4 +18,4 @@ void downgrade_package(const char *package_manager, const char *packages);
1618
char **list_cached_versions(const char *package, int *count);
1719
void system_health_check(void);
1820

19-
#endif
21+
#endif

src/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ int main(int argc, char *argv[]) {
114114

115115
while (1) {
116116
char input_line[MAX_INPUT_LENGTH];
117-
get_input(input_line, "\033[1;32mArchium $ \033[0m");
117+
get_input(input_line, sizeof(input_line), "\033[1;32mArchium $ \033[0m");
118118

119119
if (*input_line) {
120120
add_history(input_line);

src/plugin.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,13 @@ int archium_plugin_init(void) {
147147
continue;
148148
}
149149

150-
strcpy(loaded_plugins[plugin_count].name, name);
151-
strcpy(loaded_plugins[plugin_count].command, command);
152-
strcpy(loaded_plugins[plugin_count].description, description);
150+
snprintf(loaded_plugins[plugin_count].name,
151+
sizeof(loaded_plugins[plugin_count].name), "%s", name);
152+
snprintf(loaded_plugins[plugin_count].command,
153+
sizeof(loaded_plugins[plugin_count].command), "%s", command);
154+
snprintf(loaded_plugins[plugin_count].description,
155+
sizeof(loaded_plugins[plugin_count].description), "%s",
156+
description);
153157
loaded_plugins[plugin_count].handle = handle;
154158
loaded_plugins[plugin_count].execute = execute;
155159
loaded_plugins[plugin_count].get_api_version = get_api_version;

src/utils.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -251,11 +251,15 @@ void parse_and_show_generic_result(const char *output __attribute__((unused)),
251251
}
252252
}
253253

254-
void get_input(char *input, const char *prompt) {
254+
void get_input(char *input, size_t input_size, const char *prompt) {
255+
if (!input || input_size == 0) {
256+
return;
257+
}
258+
255259
while (1) {
256260
char *line = readline(prompt);
257261
if (line) {
258-
strcpy(input, line);
262+
snprintf(input, input_size, "%s", line);
259263
free(line);
260264
} else {
261265
input[0] = '\0';

0 commit comments

Comments
 (0)