aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
authorLibravatar Connor Edwards <38229097+c-edw@users.noreply.github.com>2019-01-20 14:03:30 +0000
committerLibravatar emersion <contact@emersion.fr>2019-01-20 15:03:30 +0100
commit9df3a9136c3a1c554ee97f63e57b499d353b8636 (patch)
tree3981a8657c681eec1d7c2c7848fd02a344df2042 /common
parentMerge pull request #3468 from emersion/fix-output-gain-crtc (diff)
downloadsway-9df3a9136c3a1c554ee97f63e57b499d353b8636.tar.gz
sway-9df3a9136c3a1c554ee97f63e57b499d353b8636.tar.zst
sway-9df3a9136c3a1c554ee97f63e57b499d353b8636.zip
Allocate minimum size necessary in pango text functions. (#3473)
* Allocate minimum size necessary in pango text functions. * Handle malloc failure.
Diffstat (limited to 'common')
-rw-r--r--common/pango.c34
1 files changed, 22 insertions, 12 deletions
diff --git a/common/pango.c b/common/pango.c
index db8413f7..7e164043 100644
--- a/common/pango.c
+++ b/common/pango.c
@@ -10,10 +10,6 @@
10#include "log.h" 10#include "log.h"
11#include "stringop.h" 11#include "stringop.h"
12 12
13#define MAX_CHARS 16384
14
15static const char overflow[] = "[buffer overflow]";
16
17size_t escape_markup_text(const char *src, char *dest) { 13size_t escape_markup_text(const char *src, char *dest) {
18 size_t length = 0; 14 size_t length = 0;
19 if (dest) { 15 if (dest) {
@@ -88,13 +84,19 @@ PangoLayout *get_pango_layout(cairo_t *cairo, const char *font,
88 84
89void get_text_size(cairo_t *cairo, const char *font, int *width, int *height, 85void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
90 int *baseline, double scale, bool markup, const char *fmt, ...) { 86 int *baseline, double scale, bool markup, const char *fmt, ...) {
91 char buf[MAX_CHARS];
92
93 va_list args; 87 va_list args;
94 va_start(args, fmt); 88 va_start(args, fmt);
95 if (vsnprintf(buf, sizeof(buf), fmt, args) >= MAX_CHARS) { 89 // Add one since vsnprintf excludes null terminator.
96 strcpy(&buf[sizeof(buf) - sizeof(overflow)], overflow); 90 int length = vsnprintf(NULL, 0, fmt, args) + 1;
91 va_end(args);
92
93 char *buf = malloc(length);
94 if (buf == NULL) {
95 wlr_log(WLR_ERROR, "Failed to allocate memory");
96 return;
97 } 97 }
98 va_start(args, fmt);
99 vsnprintf(buf, length, fmt, args);
98 va_end(args); 100 va_end(args);
99 101
100 PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup); 102 PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup);
@@ -104,17 +106,24 @@ void get_text_size(cairo_t *cairo, const char *font, int *width, int *height,
104 *baseline = pango_layout_get_baseline(layout) / PANGO_SCALE; 106 *baseline = pango_layout_get_baseline(layout) / PANGO_SCALE;
105 } 107 }
106 g_object_unref(layout); 108 g_object_unref(layout);
109 free(buf);
107} 110}
108 111
109void pango_printf(cairo_t *cairo, const char *font, 112void pango_printf(cairo_t *cairo, const char *font,
110 double scale, bool markup, const char *fmt, ...) { 113 double scale, bool markup, const char *fmt, ...) {
111 char buf[MAX_CHARS];
112
113 va_list args; 114 va_list args;
114 va_start(args, fmt); 115 va_start(args, fmt);
115 if (vsnprintf(buf, sizeof(buf), fmt, args) >= MAX_CHARS) { 116 // Add one since vsnprintf excludes null terminator.
116 strcpy(&buf[sizeof(buf) - sizeof(overflow)], overflow); 117 int length = vsnprintf(NULL, 0, fmt, args) + 1;
118 va_end(args);
119
120 char *buf = malloc(length);
121 if (buf == NULL) {
122 wlr_log(WLR_ERROR, "Failed to allocate memory");
123 return;
117 } 124 }
125 va_start(args, fmt);
126 vsnprintf(buf, length, fmt, args);
118 va_end(args); 127 va_end(args);
119 128
120 PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup); 129 PangoLayout *layout = get_pango_layout(cairo, font, buf, scale, markup);
@@ -125,4 +134,5 @@ void pango_printf(cairo_t *cairo, const char *font,
125 pango_cairo_update_layout(cairo, layout); 134 pango_cairo_update_layout(cairo, layout);
126 pango_cairo_show_layout(cairo, layout); 135 pango_cairo_show_layout(cairo, layout);
127 g_object_unref(layout); 136 g_object_unref(layout);
137 free(buf);
128} 138}