FSFontInfo.c revision 1bedbe3f
1/* 2 * Copyright 1990 Network Computing Devices; 3 * Portions Copyright 1987 by Digital Equipment Corporation 4 * 5 * Permission to use, copy, modify, distribute, and sell this software 6 * and its documentation for any purpose is hereby granted without fee, 7 * provided that the above copyright notice appear in all copies and 8 * that both that copyright notice and this permission notice appear 9 * in supporting documentation, and that the names of Network Computing 10 * Devices or Digital not be used in advertising or publicity pertaining 11 * to distribution of the software without specific, written prior 12 * permission. Network Computing Devices or Digital make no representations 13 * about the suitability of this software for any purpose. It is provided 14 * "as is" without express or implied warranty. 15 * 16 * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH 17 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES 19 * OR DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES 20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 21 * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 22 * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 23 * SOFTWARE. 24 */ 25 26/* 27 28Copyright 1987, 1998 The Open Group 29 30Permission to use, copy, modify, distribute, and sell this software and its 31documentation for any purpose is hereby granted without fee, provided that 32the above copyright notice appear in all copies and that both that 33copyright notice and this permission notice appear in supporting 34documentation. 35 36The above copyright notice and this permission notice shall be included in 37all copies or substantial portions of the Software. 38 39THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 40IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 41FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 42OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 43AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 44CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 45 46Except as contained in this notice, the name of The Open Group shall not be 47used in advertising or otherwise to promote the sale, use or other dealings 48in this Software without prior written authorization from The Open Group. 49 50*/ 51#ifdef HAVE_CONFIG_H 52#include <config.h> 53#endif 54#include "FSlibint.h" 55 56char ** 57FSListFontsWithXInfo( 58 FSServer *svr, 59 const char *pattern, 60 int maxNames, 61 int *count, 62 FSXFontInfoHeader ***info, 63 FSPropInfo ***pprops, 64 FSPropOffset ***offsets, 65 unsigned char ***prop_data) 66{ 67 long nbytes; 68 int i, 69 j; 70 size_t size = 0; 71 FSXFontInfoHeader **fhdr = (FSXFontInfoHeader **) NULL; 72 FSPropInfo **pi = (FSPropInfo **) NULL; 73 FSPropOffset **po = (FSPropOffset **) NULL; 74 unsigned char **pd = (unsigned char **) NULL; 75 char **flist = NULL; 76 fsListFontsWithXInfoReply reply; 77 fsListFontsWithXInfoReq *req; 78 fsPropInfo local_pi; 79 fsPropOffset local_po; 80 Status status; 81 Bool eat_data = True; 82 83 GetReq(ListFontsWithXInfo, req); 84 req->maxNames = maxNames; 85 nbytes = req->nbytes = pattern ? strlen(pattern) : 0; 86 req->length += (nbytes + 3) >> 2; 87 _FSSend(svr, pattern, nbytes); 88 89 for (i = 0;; i++) { 90 if (FSProtocolVersion(svr) > 1) 91 { 92 status = _FSReply(svr, (fsReply *) &reply, 0, fsFalse); 93 if (status != 0 && reply.nameLength == 0) /* got last reply */ 94 break; 95 if (status) 96 _FSRead(svr, ((char *) &reply) + SIZEOF(fsGenericReply), 97 SIZEOF(fsListFontsWithXInfoReply) - 98 SIZEOF(fsGenericReply)); 99 } else { 100 status = _FSReply(svr, (fsReply *) & reply, 101 ((SIZEOF(fsListFontsWithXInfoReply) - 102 SIZEOF(fsGenericReply)) >> 2), fsFalse); 103 } 104 if (!status) { 105 eat_data = False; 106 goto badmem; 107 } 108 if (reply.nameLength == 0) /* got last reply in version 1 */ 109 break; 110 if ((i + reply.nReplies) >= size) { 111 112 if (reply.nReplies > SIZE_MAX - i - 1) 113 goto badmem; 114 size = i + reply.nReplies + 1; 115 116 if (size > SIZE_MAX / sizeof(char *)) 117 goto badmem; 118 119 if (fhdr) { 120#define ResizeArray(var, type) { \ 121 type **tmp = FSrealloc(var, sizeof(type *) * size); \ 122 if (tmp) \ 123 var = tmp; \ 124 else \ 125 goto badmem; \ 126 } 127 128 ResizeArray(fhdr, FSXFontInfoHeader) 129 ResizeArray(flist, char) 130 ResizeArray(pi, FSPropInfo) 131 ResizeArray(po, FSPropOffset) 132 ResizeArray(pd, unsigned char) 133 } else { 134#define InitArray(var, type) \ 135 if ((var = FSmalloc(sizeof(type *) * size)) == NULL) { \ 136 goto badmem; \ 137 } 138 139 InitArray(fhdr, FSXFontInfoHeader) 140 InitArray(flist, char) 141 InitArray(pi, FSPropInfo) 142 InitArray(po, FSPropOffset) 143 InitArray(pd, unsigned char) 144 } 145 } 146 fhdr[i] = FSmalloc(sizeof(FSXFontInfoHeader)); 147 if (!fhdr[i]) { 148 goto badmem; 149 } 150 FSUnpack_XFontInfoHeader(&reply, fhdr[i], FSProtocolVersion(svr)); 151 152 /* alloc space for the name */ 153 flist[i] = FSmalloc(reply.nameLength + 1); 154 if (!flist[i]) 155 goto cleanfhdr; 156 if (FSProtocolVersion(svr) == 1) 157 { 158 /* get the name */ 159 _FSReadPad(svr, flist[i], (long) reply.nameLength); 160 flist[i][reply.nameLength] = '\0'; 161 } 162 163 pi[i] = FSmalloc(sizeof(FSPropInfo)); 164 if (!pi[i]) 165 goto cleanflist; 166 _FSReadPad(svr, (char *) &local_pi, SIZEOF(fsPropInfo)); 167 pi[i]->num_offsets = local_pi.num_offsets; 168 pi[i]->data_len = local_pi.data_len; 169 170#if SIZE_MAX <= UINT_MAX 171 if (pi[i]->num_offsets > SIZE_MAX / sizeof(FSPropOffset)) 172 goto cleanpi; 173#endif 174 175 po[i] = FSmalloc(pi[i]->num_offsets * sizeof(FSPropOffset)); 176 if (!po[i]) 177 goto cleanpi; 178 pd[i] = FSmalloc(pi[i]->data_len); 179 if (!pd[i]) 180 goto cleanpo; 181 /* get offsets */ 182 for (j=0; j<pi[i]->num_offsets; j++) 183 { 184 _FSReadPad(svr, (char *) &local_po, SIZEOF(fsPropOffset)); 185 po[i][j].name.position = local_po.name.position; 186 po[i][j].name.length = local_po.name.length; 187 po[i][j].value.position = local_po.value.position; 188 po[i][j].value.length = local_po.value.length; 189 po[i][j].type = local_po.type; 190 } 191 192 /* get prop data */ 193 if (FSProtocolVersion(svr) == 1) 194 _FSReadPad(svr, (char *) pd[i], pi[i]->data_len); 195 else 196 _FSRead(svr, (char *) pd[i], pi[i]->data_len); 197 198 if (FSProtocolVersion(svr) != 1) 199 { 200 /* get the name */ 201 _FSRead(svr, flist[i], (long) reply.nameLength); 202 flist[i][reply.nameLength] = '\0'; 203 204 nbytes = pi[i]->data_len + reply.nameLength; 205 _FSEatData(svr, (unsigned long) (((nbytes+3)&~3) - nbytes)); 206 } 207 /* avoid integer overflow */ 208 if (i > INT_MAX - 1) { 209 goto cleanpd; 210 } 211 } 212 *info = fhdr; 213 *count = i; 214 *pprops = pi; 215 *offsets = po; 216 *prop_data = pd; 217 SyncHandle(); 218 return flist; 219 220/* Error cleanup for when we're partway through filling in item #i in arrays */ 221cleanpd: 222 FSfree(pd[i]); 223cleanpo: 224 FSfree(po[i]); 225cleanpi: 226 FSfree(pi[i]); 227cleanflist: 228 FSfree(flist[i]); 229cleanfhdr: 230 FSfree(fhdr[i]); 231/* Error cleanup for all previously filled in items in the arrays */ 232badmem: 233 for (j = (i - 1); j >= 0; j--) { 234 FSfree(pi[j]); 235 FSfree(po[j]); 236 FSfree(pd[j]); 237 FSfree(flist[j]); 238 FSfree(fhdr[j]); 239 } 240 FSfree(flist); 241 FSfree(fhdr); 242 FSfree(pi); 243 FSfree(po); 244 FSfree(pd); 245 246 if (eat_data) { 247 do { 248 fsPropInfo ti; 249 250 _FSEatData(svr, (reply.nameLength + 3) & ~3); 251 _FSReadPad(svr, (char *) &ti, SIZEOF(fsPropInfo)); 252 _FSEatData(svr, (SIZEOF(fsPropOffset) * ti.num_offsets)); 253 _FSEatData(svr, ti.data_len); 254 } while (_FSReply(svr, (fsReply *) &reply, 255 ((SIZEOF(fsListFontsWithXInfoReply) 256 - SIZEOF(fsGenericReply)) >> 2), fsFalse) 257 && (reply.nameLength != 0)); 258 } 259 SyncHandle(); 260 return (char **) NULL; 261} 262