FSFontInfo.c revision ba6a1819
1/* $Xorg: FSFontInfo.c,v 1.4 2001/02/09 02:03:25 xorgcvs Exp $ */
2/*
3 * Copyright 1990 Network Computing Devices;
4 * Portions Copyright 1987 by Digital Equipment Corporation
5 *
6 * Permission to use, copy, modify, distribute, and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation, and that the names of Network Computing
11 * Devices or Digital not be used in advertising or publicity pertaining
12 * to distribution of the software without specific, written prior
13 * permission. Network Computing Devices or Digital make no representations
14 * about the suitability of this software for any purpose.  It is provided
15 * "as is" without express or implied warranty.
16 *
17 * NETWORK COMPUTING DEVICES AND  DIGITAL DISCLAIM ALL WARRANTIES WITH
18 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES
20 * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
23 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24 * SOFTWARE.
25 */
26/* $XFree86: xc/lib/FS/FSFontInfo.c,v 1.5tsi Exp $ */
27
28/*
29
30Copyright 1987, 1998  The Open Group
31
32Permission to use, copy, modify, distribute, and sell this software and its
33documentation for any purpose is hereby granted without fee, provided that
34the above copyright notice appear in all copies and that both that
35copyright notice and this permission notice appear in supporting
36documentation.
37
38The above copyright notice and this permission notice shall be included in
39all copies or substantial portions of the Software.
40
41THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
42IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
43FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
44OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
45AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
46CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
47
48Except as contained in this notice, the name of The Open Group shall not be
49used in advertising or otherwise to promote the sale, use or other dealings
50in this Software without prior written authorization from The Open Group.
51
52*/
53#ifdef HAVE_CONFIG_H
54#include <config.h>
55#endif
56#include	"FSlibint.h"
57
58char      **
59FSListFontsWithXInfo(
60    FSServer		  *svr,
61    char		  *pattern,
62    int			   maxNames,
63    int			  *count,
64    FSXFontInfoHeader	***info,
65    FSPropInfo		***pprops,
66    FSPropOffset	***offsets,
67    unsigned char	***prop_data)
68{
69    long        nbytes;
70    int         i,
71                j;
72    size_t      size = 0;
73    FSXFontInfoHeader **fhdr = (FSXFontInfoHeader **) 0;
74    FSPropInfo **pi = (FSPropInfo **) 0;
75    FSPropOffset **po = (FSPropOffset **) 0;
76    unsigned char **pd = (unsigned char **) 0;
77    char      **flist = NULL;
78    fsListFontsWithXInfoReply reply;
79    fsListFontsWithXInfoReq *req;
80    fsPropInfo local_pi;
81    fsPropOffset local_po;
82    Status status;
83
84    GetReq(ListFontsWithXInfo, req);
85    req->maxNames = maxNames;
86    nbytes = req->nbytes = pattern ? strlen(pattern) : 0;
87    req->length += (nbytes + 3) >> 2;
88    _FSSend(svr, pattern, nbytes);
89
90    for (i = 0;; i++) {
91	if (FSProtocolVersion(svr) > 1)
92	{
93	    status = _FSReply(svr, (fsReply *) &reply, 0, fsFalse);
94	    if (status != 0  &&  reply.nameLength == 0)	/* got last reply */
95		break;
96	    if (status)
97		_FSRead(svr, ((char *) &reply) + SIZEOF(fsGenericReply),
98			SIZEOF(fsListFontsWithXInfoReply) -
99			SIZEOF(fsGenericReply));
100	} else {
101	    status = _FSReply(svr, (fsReply *) & reply,
102			      ((SIZEOF(fsListFontsWithXInfoReply) -
103				SIZEOF(fsGenericReply)) >> 2), fsFalse);
104	}
105	if (!status) {
106	    for (j = (i - 1); j >= 0; j--) {
107		FSfree((char *) fhdr[j]);
108		FSfree((char *) pi[j]);
109		FSfree((char *) po[j]);
110		FSfree((char *) pd[j]);
111		FSfree(flist[j]);
112	    }
113	    if (flist)
114		FSfree((char *) flist);
115	    if (fhdr)
116		FSfree((char *) fhdr);
117	    if (pi)
118		FSfree((char *) pi);
119	    if (po)
120		FSfree((char *) po);
121	    if (pd)
122		FSfree((char *) pd);
123
124	    SyncHandle();
125	    return (char **) NULL;
126	}
127	if (reply.nameLength == 0)	/* got last reply in version 1 */
128	    break;
129	if ((i + reply.nReplies) >= size) {
130
131	    if (reply.nReplies > SIZE_MAX - i - 1)
132		goto badmem;
133	    size = i + reply.nReplies + 1;
134
135	    if (size > SIZE_MAX / sizeof(char *))
136		goto badmem;
137
138	    if (fhdr) {
139		FSXFontInfoHeader **tmp_fhdr = (FSXFontInfoHeader **)
140		FSrealloc((char *) fhdr,
141			  (unsigned) (sizeof(FSXFontInfoHeader *) * size));
142		char      **tmp_flist = (char **) FSrealloc((char *) flist,
143					 (unsigned) (sizeof(char *) * size));
144		FSPropInfo **tmp_pi = (FSPropInfo **)
145		FSrealloc((char *) pi,
146			  (unsigned) (sizeof(FSPropInfo *) * size));
147		FSPropOffset **tmp_po = (FSPropOffset **)
148		FSrealloc((char *) po,
149			  (unsigned) (sizeof(FSPropOffset *) * size));
150		unsigned char **tmp_pd = (unsigned char **)
151		FSrealloc((char *) pd,
152			  (unsigned) (sizeof(unsigned char *) * size));
153
154		if (!tmp_fhdr || !tmp_flist || !tmp_pi || !tmp_po || !tmp_pd) {
155		    for (j = (i - 1); j >= 0; j--) {
156			FSfree((char *) flist[j]);
157			FSfree((char *) fhdr[j]);
158			FSfree((char *) pi[j]);
159			FSfree((char *) po[j]);
160			FSfree((char *) pd[j]);
161		    }
162		    if (tmp_flist)
163			FSfree((char *) tmp_flist);
164		    else
165			FSfree((char *) flist);
166		    if (tmp_fhdr)
167			FSfree((char *) tmp_fhdr);
168		    else
169			FSfree((char *) fhdr);
170		    if (tmp_pi)
171			FSfree((char *) tmp_pi);
172		    else
173			FSfree((char *) pi);
174		    if (tmp_po)
175			FSfree((char *) tmp_po);
176		    else
177			FSfree((char *) po);
178		    if (tmp_pd)
179			FSfree((char *) tmp_pd);
180		    else
181			FSfree((char *) pd);
182		    goto clearwire;
183		}
184		fhdr = tmp_fhdr;
185		flist = tmp_flist;
186		pi = tmp_pi;
187		po = tmp_po;
188		pd = tmp_pd;
189	    } else {
190		if (!(fhdr = (FSXFontInfoHeader **)
191		      FSmalloc((unsigned) (sizeof(FSXFontInfoHeader *) * size))))
192		    goto clearwire;
193		if (!(flist = (char **)
194		      FSmalloc((unsigned) (sizeof(char *) * size)))) {
195		    FSfree((char *) fhdr);
196		    goto clearwire;
197		}
198		if (!(pi = (FSPropInfo **)
199		      FSmalloc((unsigned) (sizeof(FSPropInfo *) * size)))) {
200		    FSfree((char *) fhdr);
201		    FSfree((char *) flist);
202		    goto clearwire;
203		}
204		if (!(po = (FSPropOffset **)
205		      FSmalloc((unsigned) (sizeof(FSPropOffset *) * size)))) {
206		    FSfree((char *) fhdr);
207		    FSfree((char *) flist);
208		    FSfree((char *) pi);
209		    goto clearwire;
210		}
211		if (!(pd = (unsigned char **)
212		    FSmalloc((unsigned) (sizeof(unsigned char *) * size)))) {
213		    FSfree((char *) fhdr);
214		    FSfree((char *) flist);
215		    FSfree((char *) pi);
216		    FSfree((char *) po);
217		    goto clearwire;
218		}
219	    }
220	}
221	fhdr[i] = (FSXFontInfoHeader *) FSmalloc(sizeof(FSXFontInfoHeader));
222	if (!fhdr[i]) {
223	    goto badmem;
224	}
225	FSUnpack_XFontInfoHeader(&reply, fhdr[i], FSProtocolVersion(svr));
226
227	/* alloc space for the name */
228	flist[i] = (char *) FSmalloc((unsigned int) (reply.nameLength + 1));
229	if (FSProtocolVersion(svr) == 1)
230	{
231	    /* get the name */
232	    if (!flist[i]) {
233		nbytes = (reply.nameLength + 3) & ~3;
234		_FSEatData(svr, (unsigned long) nbytes);
235		goto badmem;
236	    }
237	    _FSReadPad(svr, flist[i], (long) reply.nameLength);
238	    flist[i][reply.nameLength] = '\0';
239	}
240
241	pi[i] = (FSPropInfo *) FSmalloc(sizeof(FSPropInfo));
242	if (!pi[i]) {
243	    FSfree((char *) fhdr[i]);
244	    goto badmem;
245	}
246	_FSReadPad(svr, (char *) &local_pi, SIZEOF(fsPropInfo));
247	pi[i]->num_offsets = local_pi.num_offsets;
248	pi[i]->data_len = local_pi.data_len;
249
250#if SIZE_MAX <= UINT_MAX
251	if (pi[i]->num_offsets > SIZE_MAX / sizeof(FSPropOffset))
252	    goto badmem;
253#endif
254
255	po[i] = (FSPropOffset *)
256	    FSmalloc(pi[i]->num_offsets * sizeof(FSPropOffset));
257	if (!po[i]) {
258	    FSfree((char *) fhdr[i]);
259	    FSfree((char *) pi[i]);
260	    goto badmem;
261	}
262	pd[i] = (unsigned char *) FSmalloc(pi[i]->data_len);
263	if (!pd[i]) {
264	    FSfree((char *) fhdr[i]);
265	    FSfree((char *) pi[i]);
266	    FSfree((char *) po[i]);
267	    goto badmem;
268	}
269	/* get offsets */
270	for (j=0; j<pi[i]->num_offsets; j++)
271	{
272	    _FSReadPad(svr, (char *) &local_po, SIZEOF(fsPropOffset));
273	    po[i][j].name.position = local_po.name.position;
274	    po[i][j].name.length = local_po.name.length;
275	    po[i][j].value.position = local_po.value.position;
276	    po[i][j].value.length = local_po.value.length;
277	    po[i][j].type = local_po.type;
278	}
279
280	/* get prop data */
281	if (FSProtocolVersion(svr) == 1)
282	    _FSReadPad(svr, (char *) pd[i], pi[i]->data_len);
283	else
284	    _FSRead(svr, (char *) pd[i], pi[i]->data_len);
285
286	if (FSProtocolVersion(svr) != 1)
287	{
288	    /* get the name */
289	    if (!flist[i]) {
290		nbytes = (reply.nameLength + 3) & ~3;
291		_FSEatData(svr, (unsigned long) nbytes);
292		goto badmem;
293	    }
294	    _FSRead(svr, flist[i], (long) reply.nameLength);
295	    flist[i][reply.nameLength] = '\0';
296
297	    nbytes = pi[i]->data_len + reply.nameLength;
298	    _FSEatData(svr, (unsigned long) (((nbytes+3)&~3) - nbytes));
299	}
300	/* avoid integer overflow */
301	if (i > INT_MAX - 1) {
302	    goto badmem;
303	}
304    }
305    *info = fhdr;
306    *count = i;
307    *pprops = pi;
308    *offsets = po;
309    *prop_data = pd;
310    SyncHandle();
311    return flist;
312
313badmem:
314    for (j = (i - 1); j >= 0; j--) {
315	FSfree((char *) pi[j]);
316	FSfree((char *) po[j]);
317	FSfree((char *) pd[j]);
318	FSfree(flist[j]);
319	FSfree((char *) fhdr[j]);
320    }
321    if (flist)
322	FSfree((char *) flist);
323    if (fhdr)
324	FSfree((char *) fhdr);
325    if (pi)
326	FSfree((char *) pi);
327    if (po)
328	FSfree((char *) po);
329    if (pd)
330	FSfree((char *) pd);
331
332
333clearwire:
334    do {
335	fsPropInfo  ti;
336
337	_FSEatData(svr, (reply.nameLength + 3) & ~3);
338	_FSReadPad(svr, (char *) &ti, SIZEOF(fsPropInfo));
339	_FSEatData(svr, (SIZEOF(fsPropOffset) * ti.num_offsets));
340	_FSEatData(svr, ti.data_len);
341    } while (_FSReply(svr, (fsReply *) & reply,
342		      ((SIZEOF(fsListFontsWithXInfoReply)
343       - SIZEOF(fsGenericReply)) >> 2), fsFalse) && (reply.nameLength != 0));
344    SyncHandle();
345    return (char **) NULL;
346}
347