diff --git a/makefile b/makefile index 94d4ed8..a66fb14 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ # C compiler CC=gcc # alternatives: tcc, clang, zig cc -WARNINGS=-Wall +WARNINGS=-Wall -Wextra -Wpedantic -Wshadow -Wformat=2 -Wno-unused-parameter 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 DEBUG=-g diff --git a/plugins/libre_redirect/libre_redirect.c b/plugins/libre_redirect/libre_redirect.c index 08f836a..c9d6ff6 100644 --- a/plugins/libre_redirect/libre_redirect.c +++ b/plugins/libre_redirect/libre_redirect.c @@ -66,8 +66,9 @@ int libre_redirect(const char* uri, char* output) fprintf(stderr, "Unreachable state\n"); } } - // Use snprintf instead of strcpy for safety - snprintf(output, len_output, "%s", uri); + // Use strncpy with explicit null termination for safety + strncpy(output, uri, len_output - 1); + output[len_output - 1] = '\0'; } int utm_check = str_destructively_omit_from(output, "?utm"); diff --git a/plugins/readability/readability.c b/plugins/readability/readability.c index 13670ce..674fbd7 100644 --- a/plugins/readability/readability.c +++ b/plugins/readability/readability.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,27 +6,29 @@ void read_readability_js(char* string) { - FILE* fp = fopen("/opt/rosenrot/readability.js", "r"); - if (!fp) { // fp is NULL, fopen failed - fprintf(stderr, "Failed to open file\n"); + gchar* file_contents = NULL; + gsize length = 0; + GError* error = NULL; + + if (!g_file_get_contents("/opt/rosenrot/readability.js", &file_contents, &length, &error)) { + fprintf(stderr, "Failed to open file: %s\n", error ? error->message : "unknown error"); fprintf(stderr, "Consider running $ sudo make runtime_files\n"); - string = NULL; + if (error) g_error_free(error); + string[0] = '\0'; return; } - int i = 0; - int c; - 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; + + if (length > READABILITY_N) { + fprintf(stderr, "readability.js file is too large (%zu bytes, max %d)\n", length, READABILITY_N); + fprintf(stderr, "Consider increasing READABILITY_N or running recompute_READABILITY_N.sh\n"); + g_free(file_contents); + string[0] = '\0'; + return; } - string[i] = '\0'; - fclose(fp); + + memcpy(string, file_contents, length); + string[length] = '\0'; + g_free(file_contents); } /* diff --git a/plugins/shortcuts/shortcuts.c b/plugins/shortcuts/shortcuts.c index ec7acbd..4afc58f 100644 --- a/plugins/shortcuts/shortcuts.c +++ b/plugins/shortcuts/shortcuts.c @@ -62,8 +62,9 @@ int shortcut_expand(const char* uri, char* output) fprintf(stderr, "Unreachable state\n"); } } - // Use snprintf instead of strcpy for safety - snprintf(output, len_output, "%s", uri); + // Use strncpy with explicit null termination for safety + strncpy(output, uri, len_output - 1); + output[len_output - 1] = '\0'; } if (DEBUG) printf("No match found\n\n"); return 0; diff --git a/plugins/strings/strings.c b/plugins/strings/strings.c index 632463b..c16a67a 100644 --- a/plugins/strings/strings.c +++ b/plugins/strings/strings.c @@ -49,8 +49,9 @@ int str_replace_start(const char* string, const char* target, const char* replac return 2; // success } else { if (DEBUG) printf("Did not find match.\n"); - // Use snprintf instead of strcpy for safety - snprintf(output, l4, "%s", string); + // Use strncpy with explicit null termination for safety + strncpy(output, string, l4 - 1); + output[l4 - 1] = '\0'; } return 0; diff --git a/plugins/style/style.c b/plugins/style/style.c index 1ac7b3f..aabf2a3 100644 --- a/plugins/style/style.c +++ b/plugins/style/style.c @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,24 +6,26 @@ void read_style_js(char* string) { - FILE* fp = fopen("/opt/rosenrot/style.js", "r"); - if (!fp) { // fp is NULL, fopen failed - fprintf(stderr, "Failed to open file\n"); - string = NULL; + gchar* file_contents = NULL; + gsize length = 0; + GError* error = NULL; + + if (!g_file_get_contents("/opt/rosenrot/style.js", &file_contents, &length, &error)) { + fprintf(stderr, "Failed to open file: %s\n", error ? error->message : "unknown error"); + if (error) g_error_free(error); + string[0] = '\0'; return; } - int i = 0; - int c; - 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; + + if (length > STYLE_N) { + fprintf(stderr, "style.js file is too large (%zu bytes, max %d)\n", length, STYLE_N); + fprintf(stderr, "Consider increasing STYLE_N or running recompute_STYLE_N.sh\n"); + g_free(file_contents); + string[0] = '\0'; + return; } - string[i] = '\0'; - fclose(fp); + + memcpy(string, file_contents, length); + string[length] = '\0'; + g_free(file_contents); }