From bed4877d7ba11e9212867074e3a82e622d2db3dc Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 21 Dec 2014 14:58:10 +0100 Subject: [PATCH 1/4] Fix/simplify notification_strip_markup - Strip markup before interpreting entitites. - Handle *any* tag uniformly ( is also handled by pango) --- notification.c | 58 +++++++++++++++++++------------------------------- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/notification.c b/notification.c index b0b12a4..5be57fd 100644 --- a/notification.c +++ b/notification.c @@ -191,25 +191,8 @@ char *notification_strip_markup(char *str) return NULL; } - str = string_replace_all(""", "\"", str); - str = string_replace_all("'", "'", str); - str = string_replace_all("&", "&", str); - str = string_replace_all("<", "<", str); - str = string_replace_all(">", ">", str); - - /* remove tags */ - str = string_replace_all("", "", str); - str = string_replace_all("", "", str); - str = string_replace_all("
", " ", str); - str = string_replace_all("
", " ", str); - str = string_replace_all("
", " ", str); - str = string_replace_all("", "", str); - str = string_replace_all("", "", str); - str = string_replace_all("", "", str); - str = string_replace_all("", "", str); - str = string_replace_all("", "", str); - - while ((start = strstr(str, ""); if (end != NULL) { replace_buf = strndup(start, end - start + 1); @@ -220,16 +203,13 @@ char *notification_strip_markup(char *str) } } - while ((start = strstr(str, ""); - if (end != NULL) { - replace_buf = strndup(start, end - start + 2); - str = string_replace(replace_buf, "", str); - free(replace_buf); - } else { - break; - } - } + /* unquote the remainder */ + str = string_replace_all(""", "\"", str); + str = string_replace_all("'", "'", str); + str = string_replace_all("&", "&", str); + str = string_replace_all("<", "<", str); + str = string_replace_all(">", ">", str); + return str; } @@ -270,19 +250,25 @@ char *notification_replace_format(const char *needle, const char *replacement, tmp = notification_quote_markup(tmp); ret = string_replace_all(needle, tmp, haystack); free(tmp); - } else if (!allow_markup) { + } else { tmp = strdup(replacement); - if (!settings.ignore_newline) { + if (settings.ignore_newline) { + tmp = string_replace_all("
", " ", tmp); + tmp = string_replace_all("
", " ", tmp); + tmp = string_replace_all("
", " ", tmp); + } else { tmp = string_replace_all("
", "\n", tmp); tmp = string_replace_all("
", "\n", tmp); tmp = string_replace_all("
", "\n", tmp); } - tmp = notification_strip_markup(tmp); - tmp = notification_quote_markup(tmp); + + if (!allow_markup) { + tmp = notification_strip_markup(tmp); + tmp = notification_quote_markup(tmp); + } + ret = string_replace_all(needle, tmp, haystack); free(tmp); - } else { - ret = string_replace_all(needle, replacement, haystack); } return ret; @@ -320,7 +306,7 @@ char *notification_extract_markup_urls(char **str_ptr) { } free(replace_buf); } else { - break; + break; } } *str_ptr = str; From 4b53e44d92fc04d9ca822333413838c941878cee Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 21 Dec 2014 22:05:16 +0100 Subject: [PATCH 2/4] Avoid allocations by performing stripping in-place Introduce a helper function (string_strip_delimited). --- notification.c | 13 +------------ utils.c | 15 +++++++++++++++ utils.h | 3 +++ 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/notification.c b/notification.c index 5be57fd..f96931f 100644 --- a/notification.c +++ b/notification.c @@ -185,23 +185,12 @@ void notification_free(notification * n) */ char *notification_strip_markup(char *str) { - char *replace_buf, *start, *end; - if (str == NULL) { return NULL; } /* strip all tags */ - while ((start = strstr(str, "<")) != NULL) { - end = strstr(start, ">"); - if (end != NULL) { - replace_buf = strndup(start, end - start + 1); - str = string_replace(replace_buf, "", str); - free(replace_buf); - } else { - break; - } - } + string_strip_delimited(str, '<', '>'); /* unquote the remainder */ str = string_replace_all(""", "\"", str); diff --git a/utils.c b/utils.c index 0ab4b3a..c162024 100644 --- a/utils.c +++ b/utils.c @@ -105,6 +105,21 @@ char **string_to_argv(const char *s) return argv; } +void string_strip_delimited(char *str, char a, char b) +{ + int iread=-1, iwrite=0, copen=0; + while (str[++iread] != 0) { + if (str[iread] == a) { + ++copen; + } else if (str[iread] == b && copen > 0) { + --copen; + } else if (copen == 0) { + str[iwrite++] = str[iread]; + } + } + str[iwrite] = 0; +} + int digit_count(int i) { i = ABS(i); diff --git a/utils.h b/utils.h index 9617301..1009f96 100644 --- a/utils.h +++ b/utils.h @@ -17,6 +17,9 @@ char *string_append(char *a, const char *b, const char *sep); char **string_to_argv(const char *s); +/* strip content between two delimiter characters (inplace) */ +void string_strip_delimited(char *str, char a, char b); + /* exit with an error message */ void die(char *msg, int exit_value); From 98566667c70036bfe4ab1471d29c5ee32413401b Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 21 Dec 2014 22:12:54 +0100 Subject: [PATCH 3/4] Consistent indentation. --- utils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils.c b/utils.c index c162024..99135cb 100644 --- a/utils.c +++ b/utils.c @@ -11,10 +11,10 @@ #include "dunst.h" char *string_replace_char(char needle, char replacement, char *haystack) { - char *current = haystack; - while ((current = strchr (current, needle)) != NULL) - *current++ = replacement; - return haystack; + char *current = haystack; + while ((current = strchr (current, needle)) != NULL) + *current++ = replacement; + return haystack; } char *string_replace_at(char *buf, int pos, int len, const char *repl) From cf910b0683de6258e12ddf75788f9beb1abe195a Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Sun, 21 Dec 2014 22:14:19 +0100 Subject: [PATCH 4/4] Avoid allocations in string_replace_at when possible. --- utils.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/utils.c b/utils.c index 99135cb..7d07ffe 100644 --- a/utils.c +++ b/utils.c @@ -25,13 +25,21 @@ char *string_replace_at(char *buf, int pos, int len, const char *repl) buf_len = strlen(buf); repl_len = strlen(repl); size = (buf_len - len) + repl_len + 1; - tmp = malloc(size); + + if (repl_len <= len) { + tmp = buf; + } else { + tmp = malloc(size); + } memcpy(tmp, buf, pos); memcpy(tmp + pos, repl, repl_len); - memcpy(tmp + pos + repl_len, buf + pos + len, buf_len - (pos + len) + 1); + memmove(tmp + pos + repl_len, buf + pos + len, buf_len - (pos + len) + 1); + + if(tmp != buf) { + free(buf); + } - free(buf); return tmp; }