2 * Copyright © 2006 Red Hat, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software
5 * and its documentation for any purpose is hereby granted without
6 * fee, provided that the above copyright notice appear in all copies
7 * and that both that copyright notice and this permission notice
8 * appear in supporting documentation, and that the name of
9 * Red Hat, Inc. not be used in advertising or publicity pertaining to
10 * distribution of the software without specific, written prior
11 * permission. Red Hat, Inc. makes no representations about the
12 * suitability of this software for any purpose. It is provided "as
13 * is" without express or implied warranty.
15 * RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
18 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
21 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: Behdad Esfahbod <behdad@behdad.org>
30 * _cairo_atsui_font_text_to_glyph with a zero-sized string crashes.
32 * Moreover, the fallback path in cairo_scaled_font_text_to_glyphs()
33 * when handling a zero-sized string, allocates a zero-sized glyph array
34 * and when NULL is returned by malloc, recognizes that as an out-of-memory
35 * error. The glibc implementation of malloc() does not return NULL from
36 * malloc(0), but I don't think it's a safe assumption.
38 * By just bailing out on zero-sized text, we fix both issues.
41 #include "cairo-test.h"
46 static cairo_test_draw_function_t draw
;
50 "Tests show_text and text_path with a zero-sized string",
56 text_extents_equal (const cairo_text_extents_t
*A
,
57 const cairo_text_extents_t
*B
)
59 return A
->x_bearing
== B
->x_bearing
&&
60 A
->y_bearing
== B
->y_bearing
&&
61 A
->width
== B
->width
&&
62 A
->height
== B
->height
&&
63 A
->x_advance
== B
->x_advance
&&
64 A
->y_advance
== B
->y_advance
;
68 font_extents_equal (const cairo_font_extents_t
*A
,
69 const cairo_font_extents_t
*B
)
71 return A
->ascent
== B
->ascent
&&
72 A
->descent
== B
->descent
&&
73 A
->height
== B
->height
&&
74 A
->max_x_advance
== B
->max_x_advance
&&
75 A
->max_y_advance
== B
->max_y_advance
;
78 static cairo_test_status_t
79 draw (cairo_t
*cr
, int width
, int height
)
81 cairo_text_extents_t extents
, nil_extents
;
82 cairo_font_extents_t font_extents
, nil_font_extents
;
83 cairo_scaled_font_t
*scaled_font
;
85 cairo_select_font_face (cr
, "Bitstream Vera Sans",
86 CAIRO_FONT_SLANT_NORMAL
,
87 CAIRO_FONT_WEIGHT_NORMAL
);
88 cairo_set_font_size (cr
, 16);
90 cairo_move_to (cr
, 10, 25);
91 cairo_show_text (cr
, NULL
);
92 cairo_show_text (cr
, "");
93 cairo_show_glyphs (cr
, NULL
, 0);
94 cairo_show_glyphs (cr
, (void*)8, 0);
96 cairo_move_to (cr
, 10, 55);
97 cairo_text_path (cr
, NULL
);
98 cairo_text_path (cr
, "");
99 cairo_glyph_path (cr
, (void*)8, 0);
102 memset (&nil_extents
, 0, sizeof (cairo_text_extents_t
));
104 memset (&extents
, 0xff, sizeof (cairo_text_extents_t
));
105 cairo_text_extents (cr
, "", &extents
);
106 if (! text_extents_equal (&extents
, &nil_extents
)) {
107 cairo_test_log ("Error: cairo_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n",
108 extents
.x_bearing
, extents
.y_bearing
,
109 extents
.width
, extents
.height
,
110 extents
.x_advance
, extents
.y_advance
);
111 return CAIRO_TEST_FAILURE
;
114 memset (&extents
, 0xff, sizeof (cairo_text_extents_t
));
115 cairo_text_extents (cr
, NULL
, &extents
);
116 if (! text_extents_equal (&extents
, &nil_extents
)) {
117 cairo_test_log ("Error: cairo_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
118 extents
.x_bearing
, extents
.y_bearing
,
119 extents
.width
, extents
.height
,
120 extents
.x_advance
, extents
.y_advance
);
121 return CAIRO_TEST_FAILURE
;
124 memset (&extents
, 0xff, sizeof (cairo_text_extents_t
));
125 cairo_glyph_extents (cr
, (void*)8, 0, &extents
);
126 if (! text_extents_equal (&extents
, &nil_extents
)) {
127 cairo_test_log ("Error: cairo_glyph_extents(); extents (%g, %g, %g, %g, %g, %g)\n",
128 extents
.x_bearing
, extents
.y_bearing
,
129 extents
.width
, extents
.height
,
130 extents
.x_advance
, extents
.y_advance
);
131 return CAIRO_TEST_FAILURE
;
134 scaled_font
= cairo_get_scaled_font (cr
);
136 memset (&extents
, 0xff, sizeof (cairo_text_extents_t
));
137 cairo_scaled_font_text_extents (scaled_font
, "", &extents
);
138 if (! text_extents_equal (&extents
, &nil_extents
)) {
139 cairo_test_log ("Error: cairo_scaled_font_text_extents(\"\"); extents (%g, %g, %g, %g, %g, %g)\n",
140 extents
.x_bearing
, extents
.y_bearing
,
141 extents
.width
, extents
.height
,
142 extents
.x_advance
, extents
.y_advance
);
143 return CAIRO_TEST_FAILURE
;
146 memset (&extents
, 0xff, sizeof (cairo_text_extents_t
));
147 cairo_scaled_font_text_extents (scaled_font
, NULL
, &extents
);
148 if (! text_extents_equal (&extents
, &nil_extents
)) {
149 cairo_test_log ("Error: cairo_scaled_font_text_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
150 extents
.x_bearing
, extents
.y_bearing
,
151 extents
.width
, extents
.height
,
152 extents
.x_advance
, extents
.y_advance
);
153 return CAIRO_TEST_FAILURE
;
156 memset (&extents
, 0xff, sizeof (cairo_text_extents_t
));
157 cairo_scaled_font_glyph_extents (scaled_font
, (void*)8, 0, &extents
);
158 if (! text_extents_equal (&extents
, &nil_extents
)) {
159 cairo_test_log ("Error: cairo_scaled_font_glyph_extents(NULL); extents (%g, %g, %g, %g, %g, %g)\n",
160 extents
.x_bearing
, extents
.y_bearing
,
161 extents
.width
, extents
.height
,
162 extents
.x_advance
, extents
.y_advance
);
163 return CAIRO_TEST_FAILURE
;
166 /* Lets also try font size 0 while here */
167 cairo_set_font_size (cr
, 0);
169 memset (&extents
, 0xff, sizeof (cairo_text_extents_t
));
170 cairo_text_extents (cr
, "test", &extents
);
171 if (! text_extents_equal (&extents
, &nil_extents
)) {
172 cairo_test_log ("Error: cairo_set_font_size(0); cairo_text_extents(\"test\"); extents (%g, %g, %g, %g, %g, %g)\n",
173 extents
.x_bearing
, extents
.y_bearing
,
174 extents
.width
, extents
.height
,
175 extents
.x_advance
, extents
.y_advance
);
176 return CAIRO_TEST_FAILURE
;
179 memset (&nil_font_extents
, 0, sizeof (cairo_font_extents_t
));
181 memset (&font_extents
, 0xff, sizeof (cairo_font_extents_t
));
182 cairo_font_extents (cr
, &font_extents
);
183 if (! font_extents_equal (&font_extents
, &nil_font_extents
)) {
184 cairo_test_log ("Error: cairo_set_font_size(0); cairo_font_extents(); extents (%g, %g, %g, %g, %g)\n",
185 font_extents
.ascent
, font_extents
.descent
,
187 font_extents
.max_x_advance
, font_extents
.max_y_advance
);
188 return CAIRO_TEST_FAILURE
;
191 scaled_font
= cairo_get_scaled_font (cr
);
193 memset (&font_extents
, 0xff, sizeof (cairo_font_extents_t
));
194 cairo_scaled_font_extents (scaled_font
, &font_extents
);
195 if (! font_extents_equal (&font_extents
, &nil_font_extents
)) {
196 cairo_test_log ("Error: cairo_set_font_size(0); cairo_scaled_font_extents(); extents (%g, %g, %g, %g, %g)\n",
197 font_extents
.ascent
, font_extents
.descent
,
199 font_extents
.max_x_advance
, font_extents
.max_y_advance
);
200 return CAIRO_TEST_FAILURE
;
203 return CAIRO_TEST_SUCCESS
;
209 return cairo_test (&test
);