Fix buffer overflows in eve.c (sf.net #3034056)
[monky] / src / fonts.c
1 /* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
2  * vim: ts=4 sw=4 noet ai cindent syntax=c
3  *
4  * Conky, a system monitor, based on torsmo
5  *
6  * Any original torsmo code is licensed under the BSD license
7  *
8  * All code written since the fork of torsmo is licensed under the GPL
9  *
10  * Please see COPYING for details
11  *
12  * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
13  * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al.
14  *      (see AUTHORS)
15  * All rights reserved.
16  *
17  * This program is free software: you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation, either version 3 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  * You should have received a copy of the GNU General Public License
27  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
28  *
29  */
30 #include "conky.h"
31 #include "fonts.h"
32 #include "logging.h"
33
34 int selected_font = 0;
35 int font_count = -1;
36 struct font_list *fonts = NULL;
37 char fontloaded = 0;
38
39 void set_font(void)
40 {
41 #ifdef XFT
42         if (use_xft) return;
43 #endif /* XFT */
44         if (font_count > -1 && fonts[selected_font].font) {
45                 XSetFont(display, window.gc, fonts[selected_font].font->fid);
46         }
47 }
48
49 void setup_fonts(void)
50 {
51         if ((output_methods & TO_X) == 0) {
52                 return;
53         }
54 #ifdef XFT
55         if (use_xft) {
56                 if (window.xftdraw) {
57                         XftDrawDestroy(window.xftdraw);
58                         window.xftdraw = 0;
59                 }
60                 window.xftdraw = XftDrawCreate(display, window.drawable,
61                                 window.visual, window.colourmap);
62         }
63 #endif /* XFT */
64         set_font();
65 }
66
67 int add_font(const char *data_in)
68 {
69         if ((output_methods & TO_X) == 0) {
70                 return 0;
71         }
72         if (font_count > MAX_FONTS) {
73                 CRIT_ERR(NULL, NULL, "you don't need that many fonts, sorry.");
74         }
75         font_count++;
76         if (font_count == 0) {
77                 if (fonts != NULL) {
78                         free(fonts);
79                 }
80                 if ((fonts = (struct font_list *) malloc(sizeof(struct font_list)))
81                                 == NULL) {
82                         CRIT_ERR(NULL, NULL, "malloc");
83                 }
84                 memset(fonts, 0, sizeof(struct font_list));
85         }
86         fonts = realloc(fonts, (sizeof(struct font_list) * (font_count + 1)));
87         memset(&fonts[font_count], 0, sizeof(struct font_list));
88         if (fonts == NULL) {
89                 CRIT_ERR(NULL, NULL, "realloc in add_font");
90         }
91         // must account for null terminator
92         if (strlen(data_in) < DEFAULT_TEXT_BUFFER_SIZE) {
93                 strncpy(fonts[font_count].name, data_in, DEFAULT_TEXT_BUFFER_SIZE);
94 #ifdef XFT
95                 fonts[font_count].font_alpha = 0xffff;
96 #endif
97         } else {
98                 CRIT_ERR(NULL, NULL, "Oops...looks like something overflowed in add_font().");
99         }
100         return font_count;
101 }
102
103 void set_first_font(const char *data_in)
104 {
105         if ((output_methods & TO_X) == 0) {
106                 return;
107         }
108         if (font_count < 0) {
109                 if ((fonts = (struct font_list *) malloc(sizeof(struct font_list)))
110                                 == NULL) {
111                         CRIT_ERR(NULL, NULL, "malloc");
112                 }
113                 memset(fonts, 0, sizeof(struct font_list));
114                 font_count++;
115         }
116         if (strlen(data_in) > 1) {
117                 strncpy(fonts[0].name, data_in, DEFAULT_TEXT_BUFFER_SIZE);
118 #ifdef XFT
119                 fonts[0].font_alpha = 0xffff;
120 #endif
121         }
122 }
123
124 void free_fonts(void)
125 {
126         int i;
127
128         if ((output_methods & TO_X) == 0) {
129                 return;
130         }
131         if(fontloaded == 0) {
132                 free(fonts);
133                 return;
134         }
135         for (i = 0; i <= font_count; i++) {
136 #ifdef XFT
137                 if (use_xft) {
138                         /*
139                          * Do we not need to close fonts with Xft? Unsure.  Not freeing the
140                          * fonts seems to incur a slight memory leak, but it also prevents
141                          * a crash.
142                          *
143                          * XftFontClose(display, fonts[i].xftfont);
144                          */
145                         fonts[i].xftfont = 0;
146                 } else
147 #endif /* XFT */
148                 {
149                         XFreeFont(display, fonts[i].font);
150                         fonts[i].font = 0;
151                 }
152         }
153         free(fonts);
154         fonts = 0;
155         font_count = -1;
156         selected_font = 0;
157 #ifdef XFT
158         if (window.xftdraw) {
159                 XftDrawDestroy(window.xftdraw);
160                 window.xftdraw = 0;
161         }
162 #endif /* XFT */
163 }
164
165 void load_fonts(void)
166 {
167         int i;
168
169         if ((output_methods & TO_X) == 0)
170                 return;
171         for (i = 0; i <= font_count; i++) {
172 #ifdef XFT
173                 /* load Xft font */
174                 if (use_xft && fonts[i].xftfont) {
175                         continue;
176                 } else if (use_xft) {
177                         fonts[i].xftfont = XftFontOpenName(display, screen,
178                                         fonts[i].name);
179                         if (fonts[i].xftfont) {
180                                 continue;
181                         }
182
183                         NORM_ERR("can't load Xft font '%s'", fonts[i].name);
184                         if ((fonts[i].xftfont = XftFontOpenName(display, screen,
185                                         "courier-12")) != NULL) {
186                                 continue;
187                         }
188
189                         NORM_ERR("can't load Xft font '%s'", "courier-12");
190
191                         if ((fonts[i].font = XLoadQueryFont(display, "fixed")) == NULL) {
192                                 CRIT_ERR(NULL, NULL, "can't load font '%s'", "fixed");
193                         }
194                         use_xft = 0;
195
196                         continue;
197                 }
198 #endif
199                 /* load normal font */
200                 if (!fonts[i].font && (fonts[i].font = XLoadQueryFont(display, fonts[i].name)) == NULL) {
201                         NORM_ERR("can't load font '%s'", fonts[i].name);
202                         if ((fonts[i].font = XLoadQueryFont(display, "fixed")) == NULL) {
203                                 CRIT_ERR(NULL, NULL, "can't load font '%s'", "fixed");
204                         }
205                 }
206         }
207         fontloaded = 1;
208 }