AI assistant cheap wins and memory safety

This commit is contained in:
NunoSempere 2025-11-24 12:46:20 -03:00
parent 092c815ff4
commit 56617754f5
9 changed files with 62 additions and 20 deletions

View File

@ -5,6 +5,7 @@ OPTIMIZED_SOME=-O3
OPTIMIZED_MORE=-Ofast -march=native -funit-at-a-time -flto # binary will not be compatible with other computers, but may be much faster OPTIMIZED_MORE=-Ofast -march=native -funit-at-a-time -flto # binary will not be compatible with other computers, but may be much faster
DEBUG=-g DEBUG=-g
STD=-std=c99 # maybe consider moving to c11 and using safer string handling STD=-std=c99 # maybe consider moving to c11 and using safer string handling
SECURITY=-fstack-protector-strong # detect stack buffer overflows at runtime
# Dependencies for WebkitGTK4/GTK3 # Dependencies for WebkitGTK4/GTK3
SRC_3=rosenrot3.c SRC_3=rosenrot3.c
@ -38,11 +39,11 @@ USER_CACHE_DIR=/home/`whoami`/.cache/rosenrot
RUNTIME_FILES_DIR=/opt/rosenrot/ RUNTIME_FILES_DIR=/opt/rosenrot/
build: $(SRC_4) $(PLUGINS) $(CONFIG) constants user_cache build: $(SRC_4) $(PLUGINS) $(CONFIG) constants user_cache
$(CC) $(STD) $(WARNINGS) $(DEPRECATION_FLAGS) $(OPTIMIZED_MORE) $(DEBUG) $(INCS_4) $(PLUGINS) $(SRC_4) -o rosenrot $(LIBS_4) $(ADBLOCK) $(CC) $(STD) $(WARNINGS) $(SECURITY) $(DEPRECATION_FLAGS) $(OPTIMIZED_MORE) $(DEBUG) $(INCS_4) $(PLUGINS) $(SRC_4) -o rosenrot $(LIBS_4) $(ADBLOCK)
@echo @echo
build3: $(SRC_3) $(PLUGINS) $(CONFIG) constants user_cache build3: $(SRC_3) $(PLUGINS) $(CONFIG) constants user_cache
$(CC) $(STD) $(WARNINGS) $(OPTIMIZED_MORE) $(DEBUG) $(INCS_3) $(PLUGINS) $(SRC_3) -o rosenrot $(LIBS_3) $(ADBLOCK) $(CC) $(STD) $(WARNINGS) $(SECURITY) $(OPTIMIZED_MORE) $(DEBUG) $(INCS_3) $(PLUGINS) $(SRC_3) -o rosenrot $(LIBS_3) $(ADBLOCK)
@echo @echo
format: $(SRC_3) $(SRC_4) $(PLUGINS) format: $(SRC_3) $(SRC_4) $(PLUGINS)
@ -65,8 +66,8 @@ uninstall:
rm $(USER_CACHE_DIR) rm $(USER_CACHE_DIR)
clean: clean:
rm rosenrot rm -f rosenrot
rm $(USER_CACHE_DIR) rm -rf $(USER_CACHE_DIR)
constants: constants:
@echo @echo
@ -102,11 +103,11 @@ lint:
fast: $(SRC) $(PLUGINS) $(CONFIG) fast: $(SRC) $(PLUGINS) $(CONFIG)
rm -f *.gcda rm -f *.gcda
GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/ GIO_MODULE_DIR=/usr/lib/x86_64-linux-gnu/gio/modules/
$(CC) $(WARNINGS) $(OPTIMIZED_MORE) -fprofile-generate $(INCS_4) $(PLUGINS) $(SRC_4) -o rosenrot $(LIBS_4) $(ADBLOCK) $(CC) $(WARNINGS) $(SECURITY) $(OPTIMIZED_MORE) -fprofile-generate $(INCS_4) $(PLUGINS) $(SRC_4) -o rosenrot $(LIBS_4) $(ADBLOCK)
@echo "Now use the browser for a while to gather some profiling data" @echo "Now use the browser for a while to gather some profiling data"
sleep 2 sleep 2
./rosenrot ./rosenrot
$(CC) $(WARNINGS) $(OPTIMIZED_MORE) -fprofile-use $(INCS_4) $(PLUGINS) $(SRC_4) -o rosenrot $(LIBS_4) $(ADBLOCK) $(CC) $(WARNINGS) $(SECURITY) $(OPTIMIZED_MORE) -fprofile-use $(INCS_4) $(PLUGINS) $(SRC_4) -o rosenrot $(LIBS_4) $(ADBLOCK)
rm -f *.gcda rm -f *.gcda
inspect: rosenrot inspect: rosenrot

View File

@ -66,7 +66,8 @@ int libre_redirect(const char* uri, char* output)
fprintf(stderr, "Unreachable state\n"); fprintf(stderr, "Unreachable state\n");
} }
} }
strcpy(output, uri); // Use snprintf instead of strcpy for safety
snprintf(output, len_output, "%s", uri);
} }
int utm_check = str_destructively_omit_from(output, "?utm"); int utm_check = str_destructively_omit_from(output, "?utm");

View File

@ -15,6 +15,13 @@ void read_readability_js(char* string)
int i = 0; int i = 0;
int c; int c;
while ((c = fgetc(fp)) != EOF) { while ((c = fgetc(fp)) != EOF) {
if (i >= READABILITY_N) {
fprintf(stderr, "readability.js file is too large (exceeds %d bytes)\n", READABILITY_N);
fprintf(stderr, "Consider increasing READABILITY_N or running recompute_READABILITY_N.sh\n");
fclose(fp);
string[0] = '\0';
return;
}
string[i++] = c; string[i++] = c;
} }
string[i] = '\0'; string[i] = '\0';

View File

@ -62,7 +62,8 @@ int shortcut_expand(const char* uri, char* output)
fprintf(stderr, "Unreachable state\n"); fprintf(stderr, "Unreachable state\n");
} }
} }
strcpy(output, uri); // Use snprintf instead of strcpy for safety
snprintf(output, len_output, "%s", uri);
} }
if (DEBUG) printf("No match found\n\n"); if (DEBUG) printf("No match found\n\n");
return 0; return 0;

View File

@ -49,7 +49,8 @@ int str_replace_start(const char* string, const char* target, const char* replac
return 2; // success return 2; // success
} else { } else {
if (DEBUG) printf("Did not find match.\n"); if (DEBUG) printf("Did not find match.\n");
strcpy(output, string); // Use snprintf instead of strcpy for safety
snprintf(output, l4, "%s", string);
} }
return 0; return 0;

View File

@ -2,4 +2,4 @@
void str_init(char* str, int n); void str_init(char* str, int n);
int str_replace_start(const char* string, const char* target, const char* replacement, char* output); int str_replace_start(const char* string, const char* target, const char* replacement, char* output);
int str_destructively_omit_from(const char* input, const char* from); int str_destructively_omit_from(char* input, const char* from);

View File

@ -14,6 +14,13 @@ void read_style_js(char* string)
int i = 0; int i = 0;
int c; int c;
while ((c = fgetc(fp)) != EOF) { while ((c = fgetc(fp)) != EOF) {
if (i >= STYLE_N) {
fprintf(stderr, "style.js file is too large (exceeds %d bytes)\n", STYLE_N);
fprintf(stderr, "Consider increasing STYLE_N or running recompute_STYLE_N.sh\n");
fclose(fp);
string[0] = '\0';
return;
}
string[i++] = c; string[i++] = c;
} }
string[i] = '\0'; string[i] = '\0';

View File

@ -48,7 +48,7 @@ void load_uri(WebKitWebView* view, const char* uri)
bool has_common_domain_extension = (strstr(uri, ".com") || strstr(uri, ".org")); bool has_common_domain_extension = (strstr(uri, ".com") || strstr(uri, ".org"));
if (has_common_domain_extension){ if (has_common_domain_extension){
char tmp[strlen("https://") + strlen(uri) + 1]; char tmp[strlen("https://") + strlen(uri) + 1];
snprintf(tmp, sizeof(tmp) + 1, "https://%s", uri); snprintf(tmp, sizeof(tmp), "https://%s", uri);
webkit_web_view_load_uri(view, tmp); webkit_web_view_load_uri(view, tmp);
return; return;
} }
@ -84,8 +84,14 @@ void set_custom_style(WebKitWebView* view)
{ {
if (custom_style_enabled) { if (custom_style_enabled) {
char* style_js = malloc(STYLE_N + 1); char* style_js = malloc(STYLE_N + 1);
if (style_js == NULL) {
fprintf(stderr, "Failed to allocate memory for style_js\n");
return;
}
read_style_js(style_js); read_style_js(style_js);
webkit_web_view_evaluate_javascript(view, style_js, -1, NULL, "rosenrot-style-plugin", NULL, NULL, NULL); if (style_js != NULL) {
webkit_web_view_evaluate_javascript(view, style_js, -1, NULL, "rosenrot-style-plugin", NULL, NULL, NULL);
}
free(style_js); free(style_js);
} }
} }
@ -347,8 +353,14 @@ int handle_shortcut(func id, GtkNotebook* notebook)
case prettify: { case prettify: {
if (READABILITY_ENABLED) { if (READABILITY_ENABLED) {
char* readability_js = malloc(READABILITY_N + 1); char* readability_js = malloc(READABILITY_N + 1);
if (readability_js == NULL) {
fprintf(stderr, "Failed to allocate memory for readability_js\n");
break;
}
read_readability_js(readability_js); read_readability_js(readability_js);
webkit_web_view_evaluate_javascript(view, readability_js, -1, NULL, "rosenrot-readability-plugin", NULL, NULL, NULL); if (readability_js != NULL) {
webkit_web_view_evaluate_javascript(view, readability_js, -1, NULL, "rosenrot-readability-plugin", NULL, NULL, NULL);
}
free(readability_js); free(readability_js);
} }
break; break;

View File

@ -52,7 +52,7 @@ void load_uri(WebKitWebView* view, const char* uri)
bool has_common_domain_extension = (strstr(uri, ".com") || strstr(uri, ".org")); bool has_common_domain_extension = (strstr(uri, ".com") || strstr(uri, ".org"));
if (has_common_domain_extension){ if (has_common_domain_extension){
char tmp[strlen("https://") + strlen(uri) + 1]; char tmp[strlen("https://") + strlen(uri) + 1];
snprintf(tmp, sizeof(tmp) + 1, "https://%s", uri); snprintf(tmp, sizeof(tmp), "https://%s", uri);
webkit_web_view_load_uri(view, tmp); webkit_web_view_load_uri(view, tmp);
return; return;
} }
@ -88,8 +88,14 @@ void set_custom_style(WebKitWebView* view)
{ {
if (custom_style_enabled) { if (custom_style_enabled) {
char* style_js = malloc(STYLE_N + 1); char* style_js = malloc(STYLE_N + 1);
if (style_js == NULL) {
fprintf(stderr, "Failed to allocate memory for style_js\n");
return;
}
read_style_js(style_js); read_style_js(style_js);
webkit_web_view_evaluate_javascript(view, style_js, -1, NULL, "rosenrot-style-plugin", NULL, NULL, NULL); if (style_js != NULL) {
webkit_web_view_evaluate_javascript(view, style_js, -1, NULL, "rosenrot-style-plugin", NULL, NULL, NULL);
}
free(style_js); free(style_js);
} }
} }
@ -262,7 +268,7 @@ void handle_signal_bar_press_enter(GtkEntry* self, GtkNotebook* notebook) /* con
case _FILTER: { case _FILTER: {
const char* js_template = "filterByKeyword(\"%s\")"; const char* js_template = "filterByKeyword(\"%s\")";
char js_command[strlen(js_template) + strlen(bar_line_text) + 2]; char js_command[strlen(js_template) + strlen(bar_line_text) + 2];
snprintf(js_command, sizeof(js_command) + 1, js_template, bar_line_text); snprintf(js_command, sizeof(js_command), js_template, bar_line_text);
webkit_web_view_evaluate_javascript(view, js_command, -1, NULL, "rosenrot-filter-plugin", NULL, NULL, NULL); webkit_web_view_evaluate_javascript(view, js_command, -1, NULL, "rosenrot-filter-plugin", NULL, NULL, NULL);
gtk_widget_set_visible(GTK_WIDGET(bar.widget), 0); gtk_widget_set_visible(GTK_WIDGET(bar.widget), 0);
@ -390,8 +396,14 @@ int handle_shortcut(func id)
case prettify: { case prettify: {
if (READABILITY_ENABLED) { if (READABILITY_ENABLED) {
char* readability_js = malloc(READABILITY_N + 1); char* readability_js = malloc(READABILITY_N + 1);
if (readability_js == NULL) {
fprintf(stderr, "Failed to allocate memory for readability_js\n");
break;
}
read_readability_js(readability_js); read_readability_js(readability_js);
webkit_web_view_evaluate_javascript(view, readability_js, -1, NULL, "rosenrot-readability-plugin", NULL, NULL, NULL); if (readability_js != NULL) {
webkit_web_view_evaluate_javascript(view, readability_js, -1, NULL, "rosenrot-readability-plugin", NULL, NULL, NULL);
}
free(readability_js); free(readability_js);
} }
break; break;
@ -413,7 +425,7 @@ int handle_shortcut(func id)
const char* uri = webkit_web_view_get_uri(view); const char* uri = webkit_web_view_get_uri(view);
const char* brave_command = "brave-browser --app=%s --new-window --start-fullscreen &"; const char* brave_command = "brave-browser --app=%s --new-window --start-fullscreen &";
char cmd[strlen(brave_command) + strlen(uri) + 2]; char cmd[strlen(brave_command) + strlen(uri) + 2];
snprintf(cmd, sizeof(cmd) + 1, brave_command, uri); snprintf(cmd, sizeof(cmd), brave_command, uri);
if(system(cmd) == -1) printf("Error opening in brave browser"); if(system(cmd) == -1) printf("Error opening in brave browser");
break; break;
} }
@ -428,14 +440,14 @@ static int handle_signal_keypress(void* self, int keyval, int keycode,
GdkModifierType state, void* controller) GdkModifierType state, void* controller)
{ {
if (1) { if (0) {
printf("New keypress\n"); printf("New keypress\n");
printf("Keypress state: %d\n", state); printf("Keypress state: %d\n", state);
printf("Keypress value: %d\n", keyval); printf("Keypress value: %d\n", keyval);
} }
for (int i = 0; i < sizeof(shortcut) / sizeof(shortcut[0]); i++) { for (int i = 0; i < sizeof(shortcut) / sizeof(shortcut[0]); i++) {
if ((state & shortcut[i].mod || shortcut[i].mod == 0x0) && keyval == shortcut[i].key) { if ((state & shortcut[i].mod || shortcut[i].mod == 0x0) && keyval == shortcut[i].key) {
printf("New shortcut, with id: %d\n", shortcut[i].id);
return handle_shortcut(shortcut[i].id); return handle_shortcut(shortcut[i].id);
} }
} }