Home | History | Annotate | Line # | Download | only in src
      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 
     28 Copyright 1987, 1998  The Open Group
     29 
     30 Permission to use, copy, modify, distribute, and sell this software and its
     31 documentation for any purpose is hereby granted without fee, provided that
     32 the above copyright notice appear in all copies and that both that
     33 copyright notice and this permission notice appear in supporting
     34 documentation.
     35 
     36 The above copyright notice and this permission notice shall be included in
     37 all copies or substantial portions of the Software.
     38 
     39 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     40 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     41 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     42 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     43 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     44 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     45 
     46 Except as contained in this notice, the name of The Open Group shall not be
     47 used in advertising or otherwise to promote the sale, use or other dealings
     48 in 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 
     56 char      **
     57 FSListFontsWithXInfo(
     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     int         i;
     68     size_t      size = 0;
     69     FSXFontInfoHeader **fhdr = (FSXFontInfoHeader **) NULL;
     70     FSPropInfo **pi = (FSPropInfo **) NULL;
     71     FSPropOffset **po = (FSPropOffset **) NULL;
     72     unsigned char **pd = (unsigned char **) NULL;
     73     char      **flist = NULL;
     74     fsListFontsWithXInfoReply reply;
     75     fsListFontsWithXInfoReq *req;
     76     fsPropInfo local_pi;
     77     fsPropOffset local_po;
     78     Status status;
     79     Bool eat_data = True;
     80 
     81     GetReq(ListFontsWithXInfo, req);
     82     req->maxNames = (CARD32) maxNames;
     83     req->nbytes = 0;
     84     if (pattern != NULL) {
     85         size_t nbytes;
     86 
     87 #ifdef HAVE_STRNLEN
     88         nbytes = strnlen(pattern, FSMaxRequestBytes(svr));
     89 #else
     90         nbytes = strlen(pattern);
     91 #endif
     92 
     93         if (nbytes <= (FSMaxRequestBytes(svr) -
     94                        SIZEOF(fsListFontsWithXInfoReq))) {
     95             req->nbytes = (CARD16) nbytes;
     96             req->length += (CARD16) ((nbytes + 3) >> 2);
     97             _FSSend(svr, pattern, (long) nbytes);
     98         }
     99     }
    100 
    101     for (i = 0;; i++) {
    102 	if (FSProtocolVersion(svr) > 1)
    103 	{
    104 	    status = _FSReply(svr, (fsReply *) &reply, 0, fsFalse);
    105 	    if (status != 0  &&  reply.nameLength == 0)	/* got last reply */
    106 		break;
    107 	    if (status)
    108 		_FSRead(svr, ((char *) &reply) + SIZEOF(fsGenericReply),
    109 			SIZEOF(fsListFontsWithXInfoReply) -
    110 			SIZEOF(fsGenericReply));
    111 	} else {
    112 	    status = _FSReply(svr, (fsReply *) & reply,
    113 			      ((SIZEOF(fsListFontsWithXInfoReply) -
    114 				SIZEOF(fsGenericReply)) >> 2), fsFalse);
    115 	}
    116 	if (!status) {
    117 	    eat_data = False;
    118 	    goto badmem;
    119 	}
    120 	if (reply.nameLength == 0)	/* got last reply in version 1 */
    121 	    break;
    122 	if ((i + reply.nReplies) >= size) {
    123 
    124 	    if (reply.nReplies > SIZE_MAX - i - 1)
    125 		goto badmem;
    126 	    size = i + reply.nReplies + 1;
    127 
    128 	    if (size > SIZE_MAX / sizeof(char *))
    129 		goto badmem;
    130 
    131 	    if (fhdr) {
    132 #define ResizeArray(var, type) { \
    133 		    type **tmp = FSreallocarray(var, size, sizeof(type *)); \
    134 		    if (tmp)						\
    135 			var = tmp;					\
    136 		    else						\
    137 			goto badmem;					\
    138 		}
    139 
    140 		ResizeArray(fhdr, FSXFontInfoHeader)
    141 		ResizeArray(flist, char)
    142 		ResizeArray(pi, FSPropInfo)
    143 		ResizeArray(po, FSPropOffset)
    144 		ResizeArray(pd, unsigned char)
    145 	    } else {
    146 #define InitArray(var, type) \
    147 		if ((var = FSmallocarray(size, sizeof(type *))) == NULL) { \
    148 		    goto badmem;					\
    149 		}
    150 
    151 		InitArray(fhdr, FSXFontInfoHeader)
    152 		InitArray(flist, char)
    153 		InitArray(pi, FSPropInfo)
    154 		InitArray(po, FSPropOffset)
    155 		InitArray(pd, unsigned char)
    156 	    }
    157 	}
    158 	fhdr[i] = FSmalloc(sizeof(FSXFontInfoHeader));
    159 	if (!fhdr[i]) {
    160 	    goto badmem;
    161 	}
    162 	FSUnpack_XFontInfoHeader(&reply, fhdr[i], FSProtocolVersion(svr));
    163 
    164 	/* alloc space for the name */
    165 	flist[i] = FSmalloc(reply.nameLength + 1);
    166 	if (!flist[i])
    167 	    goto cleanfhdr;
    168 	if (FSProtocolVersion(svr) == 1)
    169 	{
    170 	    /* get the name */
    171 	    _FSReadPad(svr, flist[i], (long) reply.nameLength);
    172 	    flist[i][reply.nameLength] = '\0';
    173 	}
    174 
    175 	pi[i] = FSmalloc(sizeof(FSPropInfo));
    176 	if (!pi[i])
    177 	    goto cleanflist;
    178 	_FSReadPad(svr, (char *) &local_pi, SIZEOF(fsPropInfo));
    179 	pi[i]->num_offsets = local_pi.num_offsets;
    180 	pi[i]->data_len = local_pi.data_len;
    181 
    182 #if SIZE_MAX <= UINT_MAX
    183 	if (pi[i]->num_offsets > SIZE_MAX / sizeof(FSPropOffset))
    184 	    goto cleanpi;
    185 #endif
    186 
    187 	po[i] = FSmallocarray(pi[i]->num_offsets, sizeof(FSPropOffset));
    188 	if (!po[i])
    189 	    goto cleanpi;
    190 	pd[i] = FSmalloc(pi[i]->data_len);
    191 	if (!pd[i])
    192 	    goto cleanpo;
    193 	/* get offsets */
    194 	for (unsigned int j = 0; j < pi[i]->num_offsets; j++)
    195 	{
    196 	    _FSReadPad(svr, (char *) &local_po, SIZEOF(fsPropOffset));
    197 	    po[i][j].name.position = local_po.name.position;
    198 	    po[i][j].name.length = local_po.name.length;
    199 	    po[i][j].value.position = local_po.value.position;
    200 	    po[i][j].value.length = local_po.value.length;
    201 	    po[i][j].type = local_po.type;
    202 	}
    203 
    204 	/* get prop data */
    205 	if (FSProtocolVersion(svr) == 1)
    206 	    _FSReadPad(svr, (char *) pd[i], pi[i]->data_len);
    207 	else
    208 	    _FSRead(svr, (char *) pd[i], pi[i]->data_len);
    209 
    210 	if (FSProtocolVersion(svr) != 1)
    211 	{
    212 	    unsigned long	nbytes;
    213 
    214 	    /* get the name */
    215 	    _FSRead(svr, flist[i], (long) reply.nameLength);
    216 	    flist[i][reply.nameLength] = '\0';
    217 
    218 	    nbytes = pi[i]->data_len + reply.nameLength;
    219 	    _FSEatData(svr, (unsigned long) (((nbytes+3)&~3) - nbytes));
    220 	}
    221 	/* avoid integer overflow */
    222 	if (i > INT_MAX - 1) {
    223 	    goto cleanpd;
    224 	}
    225     }
    226     *info = fhdr;
    227     *count = i;
    228     *pprops = pi;
    229     *offsets = po;
    230     *prop_data = pd;
    231     SyncHandle();
    232     return flist;
    233 
    234 /* Error cleanup for when we're partway through filling in item #i in arrays */
    235 cleanpd:
    236     FSfree(pd[i]);
    237 cleanpo:
    238     FSfree(po[i]);
    239 cleanpi:
    240     FSfree(pi[i]);
    241 cleanflist:
    242     FSfree(flist[i]);
    243 cleanfhdr:
    244     FSfree(fhdr[i]);
    245 /* Error cleanup for all previously filled in items in the arrays */
    246 badmem:
    247     for (int j = (i - 1); j >= 0; j--) {
    248 	FSfree(pi[j]);
    249 	FSfree(po[j]);
    250 	FSfree(pd[j]);
    251 	FSfree(flist[j]);
    252 	FSfree(fhdr[j]);
    253     }
    254     FSfree(flist);
    255     FSfree(fhdr);
    256     FSfree(pi);
    257     FSfree(po);
    258     FSfree(pd);
    259 
    260     if (eat_data) {
    261 	do {
    262 	    fsPropInfo  ti;
    263 
    264 	    _FSEatData(svr, (reply.nameLength + 3) & ~3);
    265 	    _FSReadPad(svr, (char *) &ti, SIZEOF(fsPropInfo));
    266 	    _FSEatData(svr, (SIZEOF(fsPropOffset) * ti.num_offsets));
    267 	    _FSEatData(svr, ti.data_len);
    268 	} while (_FSReply(svr, (fsReply *) &reply,
    269 			  ((SIZEOF(fsListFontsWithXInfoReply)
    270 			    - SIZEOF(fsGenericReply)) >> 2), fsFalse)
    271 		 && (reply.nameLength != 0));
    272     }
    273     SyncHandle();
    274     return (char **) NULL;
    275 }
    276