aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Heghedus Razvan <heghedus.razvan@protonmail.com>2018-05-07 19:30:45 +0300
committerLibravatar Heghedus Razvan <heghedus.razvan@gmail.com>2018-05-13 17:53:45 +0300
commit789a877b379cd35c350610be62b971ae00feb542 (patch)
tree417eb755118e7dedae3badeeaa7d713f204994e2
parentMerge pull request #1824 from snaggen/idle (diff)
downloadsway-789a877b379cd35c350610be62b971ae00feb542.tar.gz
sway-789a877b379cd35c350610be62b971ae00feb542.tar.zst
sway-789a877b379cd35c350610be62b971ae00feb542.zip
Fix crash when using pango markup font
The characters & < > ' " needs to be escaped when using pango markup Signed-off-by: Heghedus Razvan <heghedus.razvan@gmail.com>
-rw-r--r--common/pango.c73
-rw-r--r--include/pango.h11
-rw-r--r--sway/tree/view.c21
3 files changed, 99 insertions, 6 deletions
diff --git a/common/pango.c b/common/pango.c
index 658d2876..9437c60d 100644
--- a/common/pango.c
+++ b/common/pango.c
@@ -8,6 +8,68 @@
8#include <string.h> 8#include <string.h>
9#include "log.h" 9#include "log.h"
10 10
11int escape_markup_text(const char *src, char *dest, int dest_length) {
12 int length = 0;
13
14 while (src[0]) {
15 switch (src[0]) {
16 case '&':
17 length += 5;
18 if (dest && dest_length - length >= 0) {
19 dest += sprintf(dest, "%s", "&amp;");
20 } else {
21 dest_length = -1;
22 }
23 break;
24 case '<':
25 length += 4;
26 if (dest && dest_length - length >= 0) {
27 dest += sprintf(dest, "%s", "&lt;");
28 } else {
29 dest_length = -1;
30 }
31 break;
32 case '>':
33 length += 4;
34 if (dest && dest_length - length >= 0) {
35 dest += sprintf(dest, "%s", "&gt;");
36 } else {
37 dest_length = -1;
38 }
39 break;
40 case '\'':
41 length += 6;
42 if (dest && dest_length - length >= 0) {
43 dest += sprintf(dest, "%s", "&apos;");
44 } else {
45 dest_length = -1;
46 }
47 break;
48 case '"':
49 length += 6;
50 if (dest && dest_length - length >= 0) {
51 dest += sprintf(dest, "%s", "&quot;");
52 } else {
53 dest_length = -1;
54 }
55 break;
56 default:
57 length += 1;
58 if (dest && dest_length - length >= 0) {
59 *(dest++) = *src;
60 } else {
61 dest_length = -1;
62 }
63 }
64 src++;
65 }
66 // if we could not fit the escaped string in dest, return -1
67 if (dest && dest_length == -1) {
68 return -1;
69 }
70 return length;
71}
72
11PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, 73PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
12 const char *text, int32_t scale, bool markup) { 74 const char *text, int32_t scale, bool markup) {
13 PangoLayout *layout = pango_cairo_create_layout(cairo); 75 PangoLayout *layout = pango_cairo_create_layout(cairo);
@@ -15,13 +77,14 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
15 if (markup) { 77 if (markup) {
16 char *buf; 78 char *buf;
17 GError *error = NULL; 79 GError *error = NULL;
18 if (!sway_assert(pango_parse_markup( 80 bool result = pango_parse_markup(text, -1, 0, &attrs, &buf,
19 text, -1, 0, &attrs, &buf, NULL, &error), 81 NULL, &error);
20 "pango_parse_markup '%s' -> error %s", text, 82 if (result) {
21 error ? error->message : NULL)) { 83 wlr_log(L_ERROR, "pango_parse_markup '%s' -> error %s", text,
84 error->message);
22 return NULL; 85 return NULL;
23 } 86 }
24 pango_layout_set_markup(layout, buf, -1); 87 pango_layout_set_markup(layout, text, -1);
25 free(buf); 88 free(buf);
26 } else { 89 } else {
27 attrs = pango_attr_list_new(); 90 attrs = pango_attr_list_new();
diff --git a/include/pango.h b/include/pango.h
index f6325f28..d8263f9e 100644
--- a/include/pango.h
+++ b/include/pango.h
@@ -6,6 +6,17 @@
6#include <cairo/cairo.h> 6#include <cairo/cairo.h>
7#include <pango/pangocairo.h> 7#include <pango/pangocairo.h>
8 8
9/* Utility function which escape characters a & < > ' ".
10 *
11 * If the dest parameter is NULL, then the function returns the length of
12 * of the escaped src string. The dest_length doesn't matter.
13 *
14 * If the dest parameter is not NULL then the fuction escapes the src string
15 * an puts the escaped string in dest and returns the lenght of the escaped string.
16 * The dest_length parameter is the size of dest array. If the size of dest is not
17 * enough, then the function returns -1.
18 */
19int escape_markup_text(const char *src, char *dest, int dest_length);
9PangoLayout *get_pango_layout(cairo_t *cairo, const char *font, 20PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
10 const char *text, int32_t scale, bool markup); 21 const char *text, int32_t scale, bool markup);
11void get_text_size(cairo_t *cairo, const char *font, int *width, int *height, 22void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
diff --git a/sway/tree/view.c b/sway/tree/view.c
index e2cb8a7a..9bdc5198 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -14,6 +14,8 @@
14#include "sway/tree/layout.h" 14#include "sway/tree/layout.h"
15#include "sway/tree/view.h" 15#include "sway/tree/view.h"
16#include "sway/tree/workspace.h" 16#include "sway/tree/workspace.h"
17#include "sway/config.h"
18#include "pango.h"
17 19
18void view_init(struct sway_view *view, enum sway_view_type type, 20void view_init(struct sway_view *view, enum sway_view_type type,
19 const struct sway_view_impl *impl) { 21 const struct sway_view_impl *impl) {
@@ -612,6 +614,19 @@ static size_t parse_title_format(struct sway_view *view, char *buffer) {
612 return len; 614 return len;
613} 615}
614 616
617static char *escape_title(char *buffer) {
618 int length = escape_markup_text(buffer, NULL, 0);
619 char *escaped_title = calloc(length + 1, sizeof(char));
620 int result = escape_markup_text(buffer, escaped_title, length);
621 if (result != length) {
622 wlr_log(L_ERROR, "Could not escape title: %s", buffer);
623 free(escaped_title);
624 return buffer;
625 }
626 free(buffer);
627 return escaped_title;
628}
629
615void view_update_title(struct sway_view *view, bool force) { 630void view_update_title(struct sway_view *view, bool force) {
616 if (!view->swayc) { 631 if (!view->swayc) {
617 return; 632 return;
@@ -631,11 +646,15 @@ void view_update_title(struct sway_view *view, bool force) {
631 free(view->swayc->formatted_title); 646 free(view->swayc->formatted_title);
632 if (title) { 647 if (title) {
633 size_t len = parse_title_format(view, NULL); 648 size_t len = parse_title_format(view, NULL);
634 char *buffer = calloc(len + 1, 1); 649 char *buffer = calloc(len + 1, sizeof(char));
635 if (!sway_assert(buffer, "Unable to allocate title string")) { 650 if (!sway_assert(buffer, "Unable to allocate title string")) {
636 return; 651 return;
637 } 652 }
638 parse_title_format(view, buffer); 653 parse_title_format(view, buffer);
654 // now we have the title, but needs to be escaped when using pango markup
655 if (config->pango_markup) {
656 buffer = escape_title(buffer);
657 }
639 658
640 view->swayc->name = strdup(title); 659 view->swayc->name = strdup(title);
641 view->swayc->formatted_title = buffer; 660 view->swayc->formatted_title = buffer;