tmisu

Notification to stdout daemon
git clone https://git.inz.fi/tmisu/
Log | Files | Refs | README | LICENSE

commit a37b904f1d76bc0f789ca7fea98e883c6b004428
parent 76b67f37decd38d81f5a4d203d83578f1ccb9f9f
Author: Christian Glindkamp <christian.glindkamp@gmail.com>
Date:   Sat, 22 Aug 2020 17:47:12 +0200

Fix some problems in method_handler

The custom sanitize function is replaced with g_strescape, which
allocates the target buffer. This makes buffer overflows impossible and
in this case, replaces the shared buffer sanitized. This is needed,
because it is used on two occasions for two values at the same time,
thereby overwriting the first value (app_name/app_icon and
summary/body). This bug is also mention in issue #10.

Additionally, several memleaks in this function are fixed (free and
unref results of the GVariant functions).

Diffstat:
Mcallbacks.c | 55++++++++++++++++++++++++++++---------------------------
1 file changed, 28 insertions(+), 27 deletions(-)

diff --git a/callbacks.c b/callbacks.c @@ -1,26 +1,11 @@ #include <stdio.h> +#include <glib.h> #include "tiramisu.h" #include "callbacks.h" unsigned int notification_id = 0; -char *sanitize(char *string, char *out) { - memset(out, 0, strlen(out)); - - while (*string) { - if (*string == '"') - strcat(out, "\\\""); - else if (*string == '\n') - strcat(out, "\\n"); - else - out[strlen(out)] = *string; - string++; - } - - return out; -} - void method_handler(GDBusConnection *connection, const gchar *sender, const gchar *object, const gchar *interface, const gchar *method, GVariant *parameters, GDBusMethodInvocation *invocation, @@ -61,16 +46,22 @@ output: g_variant_iter_next(&iterator, "@a{sv}", &hints); g_variant_iter_next(&iterator, "i", &timeout); - char *sanitized = (char *)calloc(512, sizeof(char)); - + char *app_name_sanitized = g_strescape(app_name, ""); + char *app_icon_sanitized = g_strescape(app_icon, ""); printf( #ifdef PRINT_JSON "{ \"app_name\": \"%s\", \"app_icon\": \"%s\", ", #else "app_name: %s\napp_icon: %s\n", #endif - sanitize(app_name, sanitized), - sanitize(app_icon, sanitized)); + app_name_sanitized, + app_icon_sanitized); + + free(app_name_sanitized); + free(app_icon_sanitized); + free(app_name); + free(app_icon); + printf( #ifdef PRINT_JSON "\"replaces_id\": \"%u\", \"timeout\": \"%d\", ", @@ -107,15 +98,17 @@ output: /* There has to be a better way. glib, why? */ - if ((value = g_variant_lookup_value(hints, key, GT_STRING))) + if ((value = g_variant_lookup_value(hints, key, GT_STRING))) { + char *value_sanitized = g_strescape(g_variant_get_string(value, NULL), ""); printf( #ifdef PRINT_JSON "\"%s\": \"%s\"", #else "\t%s: %s\n", #endif - key, sanitize(g_variant_dup_string(value, NULL), sanitized)); - else if ((value = g_variant_lookup_value(hints, key, GT_INT16))) + key, value_sanitized); + free(value_sanitized); + } else if ((value = g_variant_lookup_value(hints, key, GT_INT16))) printf(int_format, key, g_variant_get_int16(value)); else if ((value = g_variant_lookup_value(hints, key, GT_INT32))) printf(int_format, key, g_variant_get_int32(value)); @@ -153,9 +146,11 @@ output: key, g_variant_get_boolean(value)); index++; - + g_variant_unref(value); } + g_variant_unref(hints); + index = 0; #ifdef PRINT_JSON printf("}, \"actions\": {"); @@ -174,20 +169,26 @@ output: actions[index + 1], actions[index]); index += 2; } + free(actions); + char *summary_sanitized = g_strescape(summary, ""); + char *body_sanitized = g_strescape(body, ""); printf( #ifdef PRINT_JSON "}, \"summary\": \"%s\", \"body\": \"%s\" }\n", #else "summary: %s\nbody: %s\n", #endif - sanitize(summary, sanitized), - sanitize(body, sanitized)); + summary_sanitized, + body_sanitized); + free(summary_sanitized); + free(body_sanitized); + free(summary); + free(body); return_value = g_variant_new("(u)", notification_id); fflush(stdout); - free(sanitized); goto flush;