1c7b4381aSmrg/* Common utility code for interacting with libXfont from test utilities
2c7b4381aSmrg *
3c7b4381aSmrg * Note that this code is designed for test programs, and thus uses assert()
4c7b4381aSmrg * and fatal err() calls in places that real code would do error handling,
5c7b4381aSmrg * since the goal is to catch bugs faster, not help users get past problems.
6c7b4381aSmrg */
7c7b4381aSmrg
8c7b4381aSmrg/*
96a46240fSmrg * Copyright (c) 2015, 2019, Oracle and/or its affiliates.
10c7b4381aSmrg *
11c7b4381aSmrg * Permission is hereby granted, free of charge, to any person obtaining a
12c7b4381aSmrg * copy of this software and associated documentation files (the "Software"),
13c7b4381aSmrg * to deal in the Software without restriction, including without limitation
14c7b4381aSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15c7b4381aSmrg * and/or sell copies of the Software, and to permit persons to whom the
16c7b4381aSmrg * Software is furnished to do so, subject to the following conditions:
17c7b4381aSmrg *
18c7b4381aSmrg * The above copyright notice and this permission notice (including the next
19c7b4381aSmrg * paragraph) shall be included in all copies or substantial portions of the
20c7b4381aSmrg * Software.
21c7b4381aSmrg *
22c7b4381aSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23c7b4381aSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24c7b4381aSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
25c7b4381aSmrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26c7b4381aSmrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27c7b4381aSmrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28c7b4381aSmrg * DEALINGS IN THE SOFTWARE.
29c7b4381aSmrg */
30c7b4381aSmrg
31c7b4381aSmrg/* Based on code from xorg-server/dix/dixfont.c covered by this notice:
32c7b4381aSmrg
33c7b4381aSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
34c7b4381aSmrg
35c7b4381aSmrg                        All Rights Reserved
36c7b4381aSmrg
37c7b4381aSmrgPermission to use, copy, modify, and distribute this software and its
38c7b4381aSmrgdocumentation for any purpose and without fee is hereby granted,
39c7b4381aSmrgprovided that the above copyright notice appear in all copies and that
40c7b4381aSmrgboth that copyright notice and this permission notice appear in
41c7b4381aSmrgsupporting documentation, and that the name of Digital not be
42c7b4381aSmrgused in advertising or publicity pertaining to distribution of the
43c7b4381aSmrgsoftware without specific, written prior permission.
44c7b4381aSmrg
45c7b4381aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
46c7b4381aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
47c7b4381aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
48c7b4381aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
49c7b4381aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
50c7b4381aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
51c7b4381aSmrgSOFTWARE.
52c7b4381aSmrg
53c7b4381aSmrg */
54c7b4381aSmrg
55c7b4381aSmrg#include "font-test-utils.h"
56c7b4381aSmrg#include "src/util/replace.h"
57c7b4381aSmrg#include <stdio.h>
58c7b4381aSmrg#include <stdlib.h>
59c7b4381aSmrg#include <limits.h>
60c7b4381aSmrg#include <assert.h>
6160da515cSmrg#ifdef HAVE_ERR_H
62c7b4381aSmrg#include <err.h>
6360da515cSmrg#endif
6460da515cSmrg#include "src/util/replace.h"
65c7b4381aSmrg#include <X11/X.h>
66c7b4381aSmrg
67c7b4381aSmrgstatic unsigned long server_generation;
68c7b4381aSmrgstatic xfont2_fpe_funcs_rec const **fpe_functions;
69c7b4381aSmrgstatic int num_fpe_types;
70c7b4381aSmrg
71c7b4381aSmrgstatic int
72c7b4381aSmrgtest_client_auth_generation(ClientPtr client)
73c7b4381aSmrg{
74c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
75c7b4381aSmrg}
76c7b4381aSmrg
77c7b4381aSmrgstatic Bool
78c7b4381aSmrgtest_client_signal(ClientPtr client)
79c7b4381aSmrg{
80c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
81c7b4381aSmrg}
82c7b4381aSmrg
83c7b4381aSmrgstatic void
84c7b4381aSmrgtest_delete_font_client_id(Font id)
85c7b4381aSmrg{
86c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
87c7b4381aSmrg}
88c7b4381aSmrg
89c7b4381aSmrgstatic void _X_ATTRIBUTE_PRINTF(1,0)
90c7b4381aSmrgtest_verrorf(const char *f, va_list ap)
91c7b4381aSmrg{
92c7b4381aSmrg    vwarn(f, ap);
93c7b4381aSmrg}
94c7b4381aSmrg
95c7b4381aSmrgstatic FontPtr
96c7b4381aSmrgtest_find_old_font(FSID id)
97c7b4381aSmrg{
98c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
99c7b4381aSmrg}
100c7b4381aSmrg
101c7b4381aSmrgstatic FontResolutionPtr
102c7b4381aSmrgtest_get_client_resolutions(int *num)
103c7b4381aSmrg{
104c7b4381aSmrg    *num = 0;
105c7b4381aSmrg    return NULL;
106c7b4381aSmrg}
107c7b4381aSmrg
108c7b4381aSmrgstatic int
109c7b4381aSmrgtest_get_default_point_size(void)
110c7b4381aSmrg{
111c7b4381aSmrg    return 120;
112c7b4381aSmrg}
113c7b4381aSmrg
114c7b4381aSmrgstatic Font
115c7b4381aSmrgtest_get_new_font_client_id(void)
116c7b4381aSmrg{
117c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
118c7b4381aSmrg}
119c7b4381aSmrg
120c7b4381aSmrgstatic uint32_t
121c7b4381aSmrgtest_get_time_in_millis(void)
122c7b4381aSmrg{
123c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
124c7b4381aSmrg}
125c7b4381aSmrg
126c7b4381aSmrgstatic int
127c7b4381aSmrgtest_init_fs_handlers(FontPathElementPtr fpe,
128c7b4381aSmrg		      FontBlockHandlerProcPtr block_handler)
129c7b4381aSmrg{
130c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
131c7b4381aSmrg}
132c7b4381aSmrg
133c7b4381aSmrg/* Callback from libXfont when each fpe handler is registered */
134c7b4381aSmrgstatic int
135c7b4381aSmrgtest_register_fpe_funcs(const xfont2_fpe_funcs_rec *funcs)
136c7b4381aSmrg{
137c7b4381aSmrg    xfont2_fpe_funcs_rec const **new;
138c7b4381aSmrg
139c7b4381aSmrg    /* grow the list */
140c7b4381aSmrg    new = reallocarray(fpe_functions, (num_fpe_types + 1),
141c7b4381aSmrg		       sizeof(xfont2_fpe_funcs_ptr));
142c7b4381aSmrg    assert (new != NULL);
143c7b4381aSmrg    fpe_functions = new;
144c7b4381aSmrg
145c7b4381aSmrg    fpe_functions[num_fpe_types] = funcs;
146c7b4381aSmrg
147c7b4381aSmrg    return num_fpe_types++;
148c7b4381aSmrg}
149c7b4381aSmrg
150c7b4381aSmrgstatic void
151c7b4381aSmrgtest_remove_fs_handlers(FontPathElementPtr fpe,
152c7b4381aSmrg			FontBlockHandlerProcPtr block_handler, Bool all)
153c7b4381aSmrg{
154c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
155c7b4381aSmrg}
156c7b4381aSmrg
157c7b4381aSmrgstatic void *
158c7b4381aSmrgtest_get_server_client(void)
159c7b4381aSmrg{
160c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
161c7b4381aSmrg}
162c7b4381aSmrg
163c7b4381aSmrgstatic int
164c7b4381aSmrgtest_set_font_authorizations(char **authorizations, int *authlen, void *client)
165c7b4381aSmrg{
166c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
167c7b4381aSmrg}
168c7b4381aSmrg
169c7b4381aSmrgstatic int
170c7b4381aSmrgtest_store_font_client_font(FontPtr pfont, Font id)
171c7b4381aSmrg{
172c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
173c7b4381aSmrg}
174c7b4381aSmrg
175c7b4381aSmrgstatic Atom
176c7b4381aSmrgtest_make_atom(const char *string, unsigned len, int makeit)
177c7b4381aSmrg{
178c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
179c7b4381aSmrg}
180c7b4381aSmrg
181c7b4381aSmrgstatic int
182c7b4381aSmrgtest_valid_atom(Atom atom)
183c7b4381aSmrg{
184c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
185c7b4381aSmrg}
186c7b4381aSmrg
187c7b4381aSmrgstatic const char *
188c7b4381aSmrgtest_name_for_atom(Atom atom)
189c7b4381aSmrg{
190c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
191c7b4381aSmrg}
192c7b4381aSmrg
193c7b4381aSmrgstatic unsigned long
194c7b4381aSmrgtest_get_server_generation(void)
195c7b4381aSmrg{
196c7b4381aSmrg    return server_generation;
197c7b4381aSmrg}
198c7b4381aSmrg
199c7b4381aSmrgstatic int
200c7b4381aSmrgtest_add_fs_fd(int fd, FontFdHandlerProcPtr handler, void *data)
201c7b4381aSmrg{
202c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
203c7b4381aSmrg}
204c7b4381aSmrg
205c7b4381aSmrgstatic void
206c7b4381aSmrgtest_remove_fs_fd(int fd)
207c7b4381aSmrg{
208c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
209c7b4381aSmrg}
210c7b4381aSmrg
211c7b4381aSmrgstatic void
212c7b4381aSmrgtest_adjust_fs_wait_for_delay(void *wt, unsigned long newdelay)
213c7b4381aSmrg{
214c7b4381aSmrg    err(BadImplementation, "%s called but not yet implemented", __func__);
215c7b4381aSmrg}
216c7b4381aSmrg
217c7b4381aSmrgstatic const xfont2_client_funcs_rec xfont2_client_funcs = {
218c7b4381aSmrg    .version = XFONT2_CLIENT_FUNCS_VERSION,
219c7b4381aSmrg    .client_auth_generation = test_client_auth_generation,
220c7b4381aSmrg    .client_signal = test_client_signal,
221c7b4381aSmrg    .delete_font_client_id = test_delete_font_client_id,
222c7b4381aSmrg    .verrorf = test_verrorf,
223c7b4381aSmrg    .find_old_font = test_find_old_font,
224c7b4381aSmrg    .get_client_resolutions = test_get_client_resolutions,
225c7b4381aSmrg    .get_default_point_size = test_get_default_point_size,
226c7b4381aSmrg    .get_new_font_client_id = test_get_new_font_client_id,
227c7b4381aSmrg    .get_time_in_millis = test_get_time_in_millis,
228c7b4381aSmrg    .init_fs_handlers = test_init_fs_handlers,
229c7b4381aSmrg    .register_fpe_funcs = test_register_fpe_funcs,
230c7b4381aSmrg    .remove_fs_handlers = test_remove_fs_handlers,
231c7b4381aSmrg    .get_server_client = test_get_server_client,
232c7b4381aSmrg    .set_font_authorizations = test_set_font_authorizations,
233c7b4381aSmrg    .store_font_client_font = test_store_font_client_font,
234c7b4381aSmrg    .make_atom = test_make_atom,
235c7b4381aSmrg    .valid_atom = test_valid_atom,
236c7b4381aSmrg    .name_for_atom = test_name_for_atom,
237c7b4381aSmrg    .get_server_generation = test_get_server_generation,
238c7b4381aSmrg    .add_fs_fd = test_add_fs_fd,
239c7b4381aSmrg    .remove_fs_fd = test_remove_fs_fd,
240c7b4381aSmrg    .adjust_fs_wait_for_delay = test_adjust_fs_wait_for_delay,
241c7b4381aSmrg};
242c7b4381aSmrg
243c7b4381aSmrg
244c7b4381aSmrgxfont2_fpe_funcs_rec const **
245c7b4381aSmrginit_font_handlers(int *fpe_function_count)
246c7b4381aSmrg{
247c7b4381aSmrg    server_generation++;
248c7b4381aSmrg    xfont2_init(&xfont2_client_funcs);
249c7b4381aSmrg    /* make sure our callbacks were called & worked */
250c7b4381aSmrg    assert (fpe_functions != NULL);
251c7b4381aSmrg    assert (num_fpe_types > 0);
252c7b4381aSmrg    *fpe_function_count = num_fpe_types;
253c7b4381aSmrg    return fpe_functions;
254c7b4381aSmrg}
255c7b4381aSmrg
256c7b4381aSmrg
257c7b4381aSmrg/* does the necessary magic to figure out the fpe type */
258c7b4381aSmrgstatic int
259c7b4381aSmrgDetermineFPEType(const char *pathname)
260c7b4381aSmrg{
261c7b4381aSmrg    int i;
262c7b4381aSmrg
263c7b4381aSmrg    /* make sure init_font_handlers was called first */
264c7b4381aSmrg    assert (num_fpe_types > 0);
265c7b4381aSmrg
266c7b4381aSmrg    for (i = 0; i < num_fpe_types; i++) {
267c7b4381aSmrg        if ((*fpe_functions[i]->name_check) (pathname))
268c7b4381aSmrg            return i;
269c7b4381aSmrg    }
270c7b4381aSmrg    return -1;
271c7b4381aSmrg}
272c7b4381aSmrg
273c7b4381aSmrg
274c7b4381aSmrgstatic const char * const default_fpes[] = {
275c7b4381aSmrg    "catalogue:/etc/X11/fontpath.d",
276c7b4381aSmrg    "built-ins"
277c7b4381aSmrg};
278c7b4381aSmrg#define num_default_fpes  (sizeof(default_fpes) / sizeof(*default_fpes))
279c7b4381aSmrg
280c7b4381aSmrgFontPathElementPtr *
281c7b4381aSmrginit_font_paths(const char * const *font_paths, int *num_fpes)
282c7b4381aSmrg{
283c7b4381aSmrg    FontPathElementPtr *fpe_list;
284c7b4381aSmrg    int i;
285c7b4381aSmrg
286c7b4381aSmrg    /* make sure init_font_handlers was called first */
287c7b4381aSmrg    assert (num_fpe_types > 0);
288c7b4381aSmrg
289c7b4381aSmrg    /* Use default if caller didn't supply any */
290c7b4381aSmrg    if (*num_fpes == 0) {
291c7b4381aSmrg	font_paths = default_fpes;
292c7b4381aSmrg	*num_fpes = num_default_fpes;
293c7b4381aSmrg    }
294c7b4381aSmrg
295c7b4381aSmrg    fpe_list = calloc(*num_fpes, sizeof(FontPathElementPtr));
296c7b4381aSmrg    assert(fpe_list != NULL);
297c7b4381aSmrg
298c7b4381aSmrg    for (i = 0; i < *num_fpes; i++) {
299c7b4381aSmrg	int result;
300c7b4381aSmrg	FontPathElementPtr fpe = calloc(1, sizeof(FontPathElementRec));
301c7b4381aSmrg	assert(fpe != NULL);
302c7b4381aSmrg
303c7b4381aSmrg	fpe->name = strdup(font_paths[i]);
304c7b4381aSmrg	assert(fpe->name != NULL);
305c7b4381aSmrg	fpe->name_length = strlen(fpe->name);
306c7b4381aSmrg	assert(fpe->name_length > 0);
307c7b4381aSmrg	/* If path is to fonts.dir file, trim it off and use the full
308c7b4381aSmrg	   directory path instead.  Simplifies testing with afl. */
309c7b4381aSmrg	if (fpe->name_length > (int) sizeof("/fonts.dir")) {
310c7b4381aSmrg	    char *tail = fpe->name + fpe->name_length -
311c7b4381aSmrg		(sizeof("/fonts.dir") - 1);
312c7b4381aSmrg
313c7b4381aSmrg	    if (strcmp(tail, "/fonts.dir") == 0) {
314c7b4381aSmrg		char *fullpath;
315c7b4381aSmrg
316c7b4381aSmrg		*tail = '\0';
317c7b4381aSmrg		fullpath = realpath(fpe->name, NULL);
318c7b4381aSmrg		assert(fullpath != NULL);
319c7b4381aSmrg		free(fpe->name);
320c7b4381aSmrg		fpe->name = fullpath;
321c7b4381aSmrg		fpe->name_length = strlen(fpe->name);
322c7b4381aSmrg		assert(fpe->name_length > 0);
323c7b4381aSmrg	    }
324c7b4381aSmrg	}
325c7b4381aSmrg	fpe->type = DetermineFPEType(fpe->name);
326c7b4381aSmrg	if (fpe->type == -1)
327c7b4381aSmrg	    err(BadFontPath, "Unable to find handler for font path %s",
328c7b4381aSmrg		fpe->name);
329c7b4381aSmrg	result = (*fpe_functions[fpe->type]->init_fpe) (fpe);
330c7b4381aSmrg	if (result != Successful)
331c7b4381aSmrg	    err(result, "init_fpe failed for font path %s: error %d",
332c7b4381aSmrg		fpe->name, result);
333c7b4381aSmrg
334c7b4381aSmrg	printf("Initialized font path element #%d: %s\n", i, fpe->name);
335c7b4381aSmrg	fpe_list[i] = fpe;
336c7b4381aSmrg    }
337c7b4381aSmrg    printf("\n");
338c7b4381aSmrg
339c7b4381aSmrg    return fpe_list;
340c7b4381aSmrg}
341