Commit message: Fix an integer overflow in init_om()

CVE-2020-14363

This can lead to a double free later, as reported by Jayden Rivers.

Signed-off-by: Matthieu Herrb <matthieu@herrb.eu>
CVE: CVE-2020-14363
CWE: CWE-190
Vulnerability description: An integer overflow vulnerability leading to a double-free was found in libX11. This flaw allows a local privileged attacker to cause an application compiled with libX11 to crash, or in some cases, result in arbitrary code execution. The highest threat from this flaw is to confidentiality, integrity as well as system availability.

Project: libx11
File: omGeneric.c

is_match_charset(
    FontData	font_data,
    char	*font_name)
{
    char *last;
    int length, name_len;

    name_len = strlen(font_name);
    last = font_name + name_len;

    length = strlen(font_data->name);
    if (length > name_len)
	return False;

    if (_XlcCompareISOLatin1(last - length, font_data->name) == 0)
	return True;

    return False;
}

Project: libx11
File: omGeneric.c

close_om(
    XOM om)
{
    XOMGenericPart *gen = XOM_GENERIC(om);
    OMData data;
    int count;

    if ((data = gen->data)) {
	for (count = gen->data_num; count-- > 0; data++) {
		Xfree(data->charset_list);
		data->charset_list = NULL;
	
	    /* free font_data for om */
		free_fontdataOM(data->font_data,data->font_data_count);
		Xfree(data->font_data);
		data->font_data = NULL;

	    /* free substitute for om */
		free_fontdataOM(data->substitute,data->substitute_num);
		Xfree(data->substitute);
		data->substitute = NULL;

	    /* free vmap for om */
		free_fontdataOM(data->vmap,data->vmap_num);
		Xfree(data->vmap);
		data->vmap = NULL;

	    /* free vrotate for om */
		Xfree(data->vrotate);
		data->vrotate = NULL;
	}
	Xfree(gen->data);
	gen->data = NULL;
    }

	Xfree(gen->object_name);
	gen->object_name = NULL;

	Xfree(om->core.res_name);
	om->core.res_name = NULL;

	Xfree(om->core.res_class);
	om->core.res_class = NULL;

    if (om->core.required_charset.charset_list &&
	om->core.required_charset.charset_count > 0){
	XFreeStringList(om->core.required_charset.charset_list);
	om->core.required_charset.charset_list = NULL;
    } else {
	Xfree((char*)om->core.required_charset.charset_list);
	om->core.required_charset.charset_list = NULL;
    }

	Xfree(om->core.orientation_list.orientation);
	om->core.orientation_list.orientation = NULL;

    Xfree(om);

    return 1;
}

Project: libx11
File: omGeneric.c

parse_vw(
    XOC		oc,
    FontSet	font_set,
    char	**name_list,
    int		count)
{
    FontData	vmap = font_set->vmap;
    VRotate	vrotate = font_set->vrotate;
    int		vmap_num = font_set->vmap_num;
    int		vrotate_num = font_set->vrotate_num;
    int		ret = 0, i = 0;

    if(vmap_num > 0) {
	if(parse_fontdata(oc, font_set, vmap, vmap_num, name_list,
			  count, C_VMAP,NULL) == -1)
	    return (-1);
    }

    if(vrotate_num > 0) {
	ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
			     name_list, count, C_VROTATE, NULL);
	if(ret == -1) {
	    return (-1);
	} else if(ret == False) {
	    CodeRange	code_range;
	    int		num_cr;
	    int		sub_num = font_set->substitute_num;

	    code_range = vrotate[0].code_range; /* ? */
	    num_cr = vrotate[0].num_cr;         /* ? */
	    for(i = 0 ; i < vrotate_num ; i++) {
		if(vrotate[i].xlfd_name)
		    Xfree(vrotate[i].xlfd_name);
	    }
	    Xfree(vrotate);

	    if(sub_num > 0) {
		vrotate = font_set->vrotate = Xcalloc(sub_num,
                                                      sizeof(VRotateRec));
		if(font_set->vrotate == (VRotate)NULL)
		    return (-1);

		for(i = 0 ; i < sub_num ; i++) {
		    vrotate[i].charset_name = font_set->substitute[i].name;
		    vrotate[i].side = font_set->substitute[i].side;
		    vrotate[i].code_range = code_range;
		    vrotate[i].num_cr = num_cr;
		}
		vrotate_num = font_set->vrotate_num = sub_num;
	    } else {
		vrotate = font_set->vrotate = (VRotate)NULL;
	    }

	    ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
				 name_list, count, C_VROTATE, NULL);
	    if(ret == -1)
		return (-1);
	}
    }

    return True;
}

Project: libx11
File: omGeneric.c

create_fontset(
    XOC oc)
{
    XOMGenericPart *gen = XOM_GENERIC(oc->core.om);
    int found_num;

    if (init_fontset(oc) == False)
        return False;

    found_num = parse_fontname(oc);
    if (found_num <= 0) {
	if (found_num == 0)
	    set_missing_list(oc);
	return False;
    }

    if (gen->on_demand_loading == True) {
	if (load_font_info(oc) == False)
	    return False;
    } else {
	if (load_font(oc) == False)
	    return False;
    }

    if (init_core_part(oc) == False)
	return False;

    if (set_missing_list(oc) == False)
	return False;

    return True;
}

Project: libx11
File: omGeneric.c

get_om_values(
    XOM om,
    XlcArgList args,
    int num_args)
{
    if (om->core.resources == NULL)
	return NULL;

    return _XlcGetValues((XPointer) om, om->core.resources,
			 om->core.num_resources, args, num_args, XlcGetMask);
}

Project: libx11
File: omGeneric.c

get_prop_name(
    Display *dpy,
    XFontStruct	*fs)
{
    unsigned long fp;

    if (XGetFontProperty(fs, XA_FONT, &fp))
	return XGetAtomName(dpy, fp);

    return (char *) NULL;
}

Project: libx11
File: omGeneric.c

create_oc(
    XOM om,
    XlcArgList args,
    int num_args)
{
    XOC oc;
    XOMGenericPart *gen = XOM_GENERIC(om);
    XOCMethodsList methods_list = oc_methods_list;
    int count;

    oc = Xcalloc(1, sizeof(XOCGenericRec));
    if (oc == NULL)
	return (XOC) NULL;

    oc->core.om = om;

    if (oc_resources[0].xrm_name == NULLQUARK)
	_XlcCompileResourceList(oc_resources, XlcNumber(oc_resources));

    if (_XlcSetValues((XPointer) oc, oc_resources, XlcNumber(oc_resources),
		      args, num_args, XlcCreateMask | XlcDefaultMask))
	goto err;

    if (oc->core.base_name_list == NULL)
	goto err;

    oc->core.resources = oc_resources;
    oc->core.num_resources = XlcNumber(oc_resources);

    if (create_fontset(oc) == False)
	goto err;

    oc->methods = &oc_generic_methods;

    if (gen->object_name) {
	count = XlcNumber(oc_methods_list);

	for ( ; count-- > 0; methods_list++) {
	    if (!_XlcCompareISOLatin1(gen->object_name, methods_list->name)) {
		oc->methods = methods_list->methods;
		break;
	    }
	}
    }

    return oc;

err:
    destroy_oc(oc);

    return (XOC) NULL;
}

Project: libx11
File: omGeneric.c

check_fontset_extents(
    XCharStruct		*overall,
    int			*logical_ascent,
    int                 *logical_descent,
    XFontStruct		*font)
{
    overall->lbearing = min(overall->lbearing, font->min_bounds.lbearing);
    overall->rbearing = max(overall->rbearing, font->max_bounds.rbearing);
    overall->ascent   = max(overall->ascent,   font->max_bounds.ascent);
    overall->descent  = max(overall->descent,  font->max_bounds.descent);
    overall->width    = max(overall->width,    font->max_bounds.width);
    *logical_ascent   = max(*logical_ascent,   font->ascent);
    *logical_descent  = max(*logical_descent,  font->descent);
}

Project: libx11
File: omGeneric.c

set_oc_values(
    XOC oc,
    XlcArgList args,
    int num_args)
{
    XOCGenericPart *gen = XOC_GENERIC(oc);
    FontSet font_set = gen->font_set;
    char *ret;
    int num = gen->font_set_num;

    if (oc->core.resources == NULL)
	return NULL;

    ret = _XlcSetValues((XPointer) oc, oc->core.resources,
			oc->core.num_resources, args, num_args, XlcSetMask);
    if(ret != NULL){
	return(ret);
    } else {
	for ( ; num-- > 0; font_set++) {
	    if (font_set->font_name == NULL)
	        continue;
	    if (font_set->vpart_initialize != 0)
	        continue;
	    if( oc->core.orientation == XOMOrientation_TTB_RTL ||
		oc->core.orientation == XOMOrientation_TTB_LTR ){
	    	load_fontdata(oc, font_set->vmap, font_set->vmap_num);
		load_fontdata(oc, (FontData) font_set->vrotate,
			    font_set->vrotate_num);
		font_set->vpart_initialize = 1;
	    }
	}
	return(NULL);
    }
}

Project: libx11
File: omGeneric.c

set_fontset_extents(
    XOC oc)
{
    XRectangle *ink = &oc->core.font_set_extents.max_ink_extent;
    XRectangle *logical = &oc->core.font_set_extents.max_logical_extent;
    XFontStruct **font_list, *font;
    XCharStruct overall;
    int logical_ascent, logical_descent;
    int	num = oc->core.font_info.num_font;

    font_list = oc->core.font_info.font_struct_list;
    font = *font_list++;
    overall = font->max_bounds;
    overall.lbearing = font->min_bounds.lbearing;
    logical_ascent = font->ascent;
    logical_descent = font->descent;

    /* For Vertical Writing start */

    while (--num > 0) {
	font = *font_list++;
	check_fontset_extents(&overall, &logical_ascent, &logical_descent,
			      font);
    }

    {
	XOCGenericPart  *gen = XOC_GENERIC(oc);
	FontSet		font_set = gen->font_set;
	FontData	font_data;
	int		font_set_num = gen->font_set_num;
	int		font_data_count;

	for( ; font_set_num-- ; font_set++) {
	    if(font_set->vmap_num > 0) {
		font_data = font_set->vmap;
		font_data_count = font_set->vmap_num;
		for( ; font_data_count-- ; font_data++) {
		    if(font_data->font != NULL) {
			check_fontset_extents(&overall, &logical_ascent,
					      &logical_descent,
					      font_data->font);
		    }
		}
	    }

	    if(font_set->vrotate_num > 0 && font_set->vrotate != NULL) {
		font_data = (FontData) font_set->vrotate;
		font_data_count = font_set->vrotate_num;
		for( ; font_data_count-- ; font_data++) {
		    if(font_data->font != NULL) {
			check_fontset_extents(&overall, &logical_ascent,
					      &logical_descent,
					      font_data->font);
		    }
		}
	    }
	}
    }

    /* For Vertical Writing start */

    ink->x = overall.lbearing;
    ink->y = -(overall.ascent);
    ink->width = overall.rbearing - overall.lbearing;
    ink->height = overall.ascent + overall.descent;

    logical->x = 0;
    logical->y = -(logical_ascent);
    logical->width = overall.width;
    logical->height = logical_ascent + logical_descent;
}

Project: libx11
File: omGeneric.c

init_vrotate(
    FontData	font_data,
    int		font_data_count,
    int		type,
    CodeRange	code_range,
    int		code_range_num)
{
    VRotate	vrotate;
    int		i;

    if(type == VROTATE_NONE)
	return (VRotate)NULL;

    vrotate = Xcalloc(font_data_count, sizeof(VRotateRec));
    if(vrotate == (VRotate) NULL)
	return False;

    for(i = 0 ; i < font_data_count ; i++) {
	vrotate[i].charset_name = font_data[i].name;
	vrotate[i].side = font_data[i].side;
	if(type == VROTATE_PART) {
	    vrotate[i].num_cr = code_range_num;
	    vrotate[i].code_range = code_range;
	}
    }

    return vrotate;
}

Project: libx11
File: omGeneric.c

init_fontset(
    XOC oc)
{
    XOCGenericPart *gen;
    FontSet font_set;
    OMData data;
    int count;

    count = XOM_GENERIC(oc->core.om)->data_num;
    data = XOM_GENERIC(oc->core.om)->data;

    font_set = Xcalloc(count, sizeof(FontSetRec));
    if (font_set == NULL)
	return False;

    gen = XOC_GENERIC(oc);
    gen->font_set_num = count;
    gen->font_set = font_set;

    for ( ; count-- > 0; data++, font_set++) {
	font_set->charset_count = data->charset_count;
	font_set->charset_list = data->charset_list;

	if((font_set->font_data = init_fontdata(data->font_data,
				  data->font_data_count)) == NULL)
	    goto err;
	font_set->font_data_count = data->font_data_count;
	if((font_set->substitute = init_fontdata(data->substitute,
				   data->substitute_num)) == NULL)
	    goto err;
	font_set->substitute_num = data->substitute_num;
	if((font_set->vmap = init_fontdata(data->vmap,
			     data->vmap_num)) == NULL)
	    goto err;
	font_set->vmap_num       = data->vmap_num;

	if(data->vrotate_type != VROTATE_NONE) {
	    /* A vrotate member is specified primary font data */
	    /* as initial value.                               */
	    if((font_set->vrotate = init_vrotate(data->font_data,
						 data->font_data_count,
						 data->vrotate_type,
						 data->vrotate,
						 data->vrotate_num)) == NULL)
		goto err;
	    font_set->vrotate_num = data->font_data_count;
	}
    }
    return True;

err:

    Xfree(font_set->font_data);
    Xfree(font_set->substitute);
    Xfree(font_set->vmap);
    Xfree(font_set->vrotate);
    Xfree(font_set);
    gen->font_set = (FontSet) NULL;
    gen->font_set_num = 0;
    return False;
}

Project: libx11
File: omGeneric.c

load_font_info(
    XOC oc)
{
    Display *dpy = oc->core.om->core.display;
    XOCGenericPart *gen = XOC_GENERIC(oc);
    FontSet font_set = gen->font_set;
    char **fn_list;
    int fn_num, num = gen->font_set_num;

    for ( ; num-- > 0; font_set++) {
	if (font_set->font_name == NULL)
	    continue;

	if (font_set->info == NULL) {
	    fn_list = XListFontsWithInfo(dpy, font_set->font_name, 1, &fn_num,
					 &font_set->info);
	    if (font_set->info == NULL)
		return False;

	    XFreeFontNames(fn_list);
	}
    }

    return True;
}

Project: libx11
File: omGeneric.c

static void destroy_fontdata(
    XOCGenericPart *gen,
    Display *dpy)
{
    FontSet	font_set = (FontSet) NULL;
    int		font_set_num = 0;

    if (gen->font_set) {
	font_set = gen->font_set;
	font_set_num = gen->font_set_num;
	for( ; font_set_num-- ; font_set++) {
	    if (font_set->font) {
		if(font_set->font->fid)
		    XFreeFont(dpy,font_set->font);
		else
		    XFreeFontInfo(NULL, font_set->font, 1);
		font_set->font = NULL;
	    }
	    if(font_set->font_data) {
		if (font_set->info)
		    XFreeFontInfo(NULL, font_set->info, 1);
		free_fontdataOC(dpy,
			font_set->font_data, font_set->font_data_count);
		Xfree(font_set->font_data);
		font_set->font_data = NULL;
	    }
	    if(font_set->substitute) {
		free_fontdataOC(dpy,
			font_set->substitute, font_set->substitute_num);
		Xfree(font_set->substitute);
		font_set->substitute = NULL;
	    }
	    if(font_set->vmap) {
		free_fontdataOC(dpy,
			font_set->vmap, font_set->vmap_num);
		Xfree(font_set->vmap);
		font_set->vmap = NULL;
	    }
	    if(font_set->vrotate) {
		free_fontdataOC(dpy,
			(FontData)font_set->vrotate,
			      font_set->vrotate_num);
		Xfree(font_set->vrotate);
		font_set->vrotate = NULL;
	    }
	}
	Xfree(gen->font_set);
	gen->font_set = NULL;
    }
}

Project: libx11
File: omGeneric.c

init_fontdata(
    FontData	font_data,
    int		font_data_count)
{
    FontData	fd;
    int		i;

    fd = Xcalloc(font_data_count, sizeof(FontDataRec));
    if(fd == (FontData) NULL)
	return False;

    for(i = 0 ; i < font_data_count ; i++)
	fd[i] = font_data[i];

    return fd;
}

Project: libx11
File: omGeneric.c

parse_omit_name(
    XOC		oc,
    FontData	font_data,
    char	*pattern)
{
    char*	last = (char *) NULL;
    char*	base_name;
    char	buf[XLFD_MAX_LEN + 1];
    int		length = 0;
    int		num_fields;
   /*
    * If the font specified by "pattern" is expandable to be
    * a member of "font_data"'s FontSet, we've found a match.
    */
    if(is_match_charset(font_data, pattern) == True) {
	if ((font_data->xlfd_name = get_font_name(oc, pattern)) != NULL) {
	    return True;
	}
    }

    length = strlen (pattern);

    if (length > XLFD_MAX_LEN)
	return -1;

    strcpy(buf, pattern);
    last = buf + length - 1;

    /* Replace the original encoding with the encoding for this FontSet. */

    /* Figure out how many fields have been specified in this xlfd. */
    for (num_fields = 0, base_name = buf; *base_name != '\0'; base_name++)
	if (*base_name == '-') num_fields++;

    switch (num_fields) {
    case 12:
	/* This is the best way to have specified the fontset.  In this
	 * case, there is no original encoding. E.g.,
         *       -*-*-*-*-*-*-14-*-*-*-*-*
	 * To this, we'll append a dash:
         *       -*-*-*-*-*-*-14-*-*-*-*-*-
	 * then append the encoding to get:
         *       -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
	 */
	/*
	 * Take care of:
	 *       -*-*-*-*-*-*-14-*-*-*-*-
	 */
	if (*(last) == '-')
	    *++last = '*';

	*++last = '-';
	break;
    case 13:
	/* Got the charset, not the encoding, zap the charset  In this
	 * case, there is no original encoding, but there is a charset. E.g.,
         *       -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990
	 * To this, we remove the charset:
         *       -*-*-*-*-*-*-14-*-*-*-*-*-
	 * then append the new encoding to get:
         *       -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
	 */
	last = strrchr (buf, '-');
	num_fields = 12;
	break;
    case 14:
	/* Both the charset and the encoding are specified.  Get rid
	 * of them so that we can append the new charset encoding.  E.g.,
         *       -*-*-*-*-*-*-14-*-*-*-*-*-jisx0212.1990-0
	 * To this, we'll remove the encoding and charset to get:
         *       -*-*-*-*-*-*-14-*-*-*-*-*-
	 * then append the new encoding to get:
         *       -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
	 */
	last = strrchr (buf, '-');
	*last = '\0';
	last = strrchr (buf, '-');
	num_fields = 12;
	break;
    default:
	if (*last != '-')
	    *++last = '-';
	break;
    }

   /* At this point, "last" is pointing to the last "-" in the
    * xlfd, and all xlfd's at this point take a form similar to:
    *       -*-*-*-*-*-*-14-*-*-*-*-*-
    * (i.e., no encoding).
    * After the strcpy, we'll end up with something similar to:
    *       -*-*-*-*-*-*-14-*-*-*-*-*-JISX0208.1990-0
    *
    * If the modified font is found in the current FontSet,
    * we've found a match.
    */

    last++;

    if ((last - buf) + strlen(font_data->name) > XLFD_MAX_LEN)
	return -1;

    strcpy(last, font_data->name);
    if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL)
	return True;

    /* This may not be needed anymore as XListFonts() takes care of this */
    if (num_fields < 12) {
	if ((last - buf) > (XLFD_MAX_LEN - 2))
	    return -1;
	*last = '*';
	*(last + 1) = '-';
	strcpy(last + 2, font_data->name);
	num_fields++;
	last+=2;
	if ((font_data->xlfd_name = get_font_name(oc, buf)) != NULL)
	    return True;
    }


    return False;
}

Project: libx11
File: omGeneric.c

init_om(
    XOM om)
{
    XLCd lcd = om->core.lcd;
    XOMGenericPart *gen = XOM_GENERIC(om);
    OMData data;
    XlcCharSet *charset_list;
    FontData font_data;
    char **required_list;
    XOrientation *orientation;
    char **value, buf[BUFSIZ], *bufptr;
    int count = 0, num = 0;
    unsigned int length = 0;

    _XlcGetResource(lcd, "XLC_FONTSET", "on_demand_loading", &value, &count);
    if (count > 0 && _XlcCompareISOLatin1(*value, "True") == 0)
	gen->on_demand_loading = True;

    _XlcGetResource(lcd, "XLC_FONTSET", "object_name", &value, &count);
    if (count > 0) {
	gen->object_name = strdup(*value);
	if (gen->object_name == NULL)
	    return False;
    }

    for (num = 0; ; num++) {

        snprintf(buf, sizeof(buf), "fs%d.charset.name", num);
        _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);

        if( count < 1){
            snprintf(buf, sizeof(buf), "fs%d.charset", num);
            _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
            if (count < 1)
                break;
        }

	data = add_data(om);
	if (data == NULL)
	    return False;

	charset_list = Xmalloc(sizeof(XlcCharSet) * count);
	if (charset_list == NULL)
	    return False;
	data->charset_list = charset_list;
	data->charset_count = count;

	while (count-- > 0){
	    *charset_list++ = _XlcGetCharSet(*value++);
        }
        snprintf(buf, sizeof(buf), "fs%d.charset.udc_area", num);
        _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
        if( count > 0){
            UDCArea udc;
            int i,flag = 0;
            udc = Xmalloc(count * sizeof(UDCAreaRec));
	    if (udc == NULL)
	        return False;
            for(i=0;i<count;i++){
                sscanf(value[i],"\\x%lx,\\x%lx", &(udc[i].start),
		       &(udc[i].end));
            }
            for(i=0;i<data->charset_count;i++){
		if(data->charset_list[i]->udc_area == NULL){
		    data->charset_list[i]->udc_area     = udc;
		    data->charset_list[i]->udc_area_num = count;
		    flag = 1;
		}
            }
	    if(flag == 0){
		Xfree(udc);
	    }
        }

        snprintf(buf, sizeof(buf), "fs%d.font.primary", num);
        _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
        if (count < 1){
            snprintf(buf, sizeof(buf), "fs%d.font", num);
            _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
            if (count < 1)
                return False;
        }

	font_data = read_EncodingInfo(count,value);
	if (font_data == NULL)
	    return False;

	data->font_data = font_data;
	data->font_data_count = count;

        snprintf(buf, sizeof(buf), "fs%d.font.substitute", num);
        _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
        if (count > 0){
            font_data = read_EncodingInfo(count,value);
            if (font_data == NULL)
	        return False;
            data->substitute      = font_data;
            data->substitute_num = count;
        } else {
            snprintf(buf, sizeof(buf), "fs%d.font", num);
            _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
            if (count < 1) {
                data->substitute      = NULL;
                data->substitute_num = 0;
	    } else {
                font_data = read_EncodingInfo(count,value);
                data->substitute      = font_data;
                data->substitute_num = count;
	    }
	}
        read_vw(lcd,data,num);
	length += strlen(data->font_data->name) + 1;
    }

    /* required charset list */
    required_list = Xmalloc(sizeof(char *) * gen->data_num);
    if (required_list == NULL)
	return False;

    om->core.required_charset.charset_list = required_list;
    om->core.required_charset.charset_count = gen->data_num;

    count = gen->data_num;
    data = gen->data;

    if (count > 0) {
	bufptr = Xmalloc(length);
	if (bufptr == NULL) {
	    Xfree(required_list);
	    return False;
	}

	for ( ; count-- > 0; data++) {
	    strcpy(bufptr, data->font_data->name);
	    *required_list++ = bufptr;
	    bufptr += strlen(bufptr) + 1;
	}
    }

    /* orientation list */
    orientation = Xmalloc(sizeof(XOrientation) * 2);
    if (orientation == NULL)
	return False;

    orientation[0] = XOMOrientation_LTR_TTB;
    orientation[1] = XOMOrientation_TTB_RTL;
    om->core.orientation_list.orientation = orientation;
    om->core.orientation_list.num_orientation = 2;

    /* directional dependent drawing */
    om->core.directional_dependent = False;

    /* contextual drawing */
    om->core.contextual_drawing = False;

    /* context dependent */
    om->core.context_dependent = False;

    return True;
}

Project: libx11
File: omGeneric.c

static CodeRange read_vrotate(
    int count,
    char **value,
    int *type,
    int *vrotate_num)
{
    CodeRange   range;
    if(!strcmp(value[0],"all")){
	*type 	     = VROTATE_ALL ;
	*vrotate_num = 0 ;
	return (NULL);
    } else if(*(value[0]) == '['){
	*type 	     = VROTATE_PART ;
        range = (CodeRange) _XlcParse_scopemaps(value[0],vrotate_num);
	return (range);
    } else {
	*type 	     = VROTATE_NONE ;
	*vrotate_num = 0 ;
	return (NULL);
    }
}

Project: libx11
File: omGeneric.c

parse_fontname(
    XOC oc)
{
    XOCGenericPart *gen = XOC_GENERIC(oc);
    FontSet     font_set;
    FontDataRec font_data_return;
    char *base_name, **name_list;
    int font_set_num = 0;
    int found_num = 0;
    int count = 0;
    int	ret;
    int i;

    name_list = _XParseBaseFontNameList(oc->core.base_name_list, &count);
    if (name_list == NULL)
	return -1;

    font_set = gen->font_set;
    font_set_num = gen->font_set_num;

   /* Loop through all of the CharSets defined in the Locale
    * database for the current Locale.
    */
    for( ; font_set_num-- > 0 ; font_set++) {
	if(font_set->font_name)
	    continue;

	if(font_set->font_data_count > 0) {

           /*
	    * If there are a non-zero number of FontSets defined
	    * for this CharSet.
            * Try to find a font for this CharSet.  If we find an
	    * acceptable font, we save the information for return
	    * to the client.  If we do not find an acceptable font,
	    * a "missing_charset" will be reported to the client
	    * for this CharSet.
	    */
	    font_data_return.xlfd_name  = NULL;
	    font_data_return.side       = XlcUnknown;

	    ret = parse_fontdata(oc, font_set, font_set->font_data,
				 font_set->font_data_count,
				 name_list, count, C_PRIMARY,
				 &font_data_return);
	    if(ret == -1) {
		goto err;
	    } else if(ret == True) {
		/*
		 * We can't just loop through fontset->font_data to
		 * find the first (ie. best) match: parse_fontdata
		 * will try a substitute font if no primary one could
		 * be matched. It returns the required information in
		 * font_data_return.
		 */
		font_set->font_name = strdup(font_data_return.xlfd_name);
		if(font_set->font_name == (char *) NULL)
		    goto err;

		font_set->side = font_data_return.side;

                Xfree (font_data_return.xlfd_name);
                font_data_return.xlfd_name = NULL;

		if(parse_vw(oc, font_set, name_list, count) == -1)
		    goto err;
		found_num++;
	    }

	} else if(font_set->substitute_num > 0) {
           /*
	    * If there are no FontSets defined for this
	    * CharSet.  We can only find "substitute" fonts.
	    */
	    ret = parse_fontdata(oc, font_set, font_set->substitute,
				 font_set->substitute_num,
				 name_list, count, C_SUBSTITUTE, NULL);
	    if(ret == -1) {
		goto err;
	    } else if(ret == True) {
		for(i=0;i<font_set->substitute_num;i++){
		    if(font_set->substitute[i].xlfd_name != NULL){
			break;
		    }
		}
		font_set->font_name = strdup(font_set->substitute[i].xlfd_name);
		if(font_set->font_name == (char *) NULL)
		    goto err;

		font_set->side = font_set->substitute[i].side;
		if(parse_vw(oc, font_set, name_list, count) == -1)
		    goto err;

		found_num++;
	    }
	}
    }

    base_name = strdup(oc->core.base_name_list);
    if (base_name == NULL)
	goto err;

    oc->core.base_name_list = base_name;

    XFreeStringList(name_list);

    return found_num;

err:
    XFreeStringList(name_list);
    /* Prevent this from being freed twice */
    oc->core.base_name_list = NULL;

    return -1;
}

Project: libx11
File: omGeneric.c

create_om(
    XLCd lcd,
    Display *dpy,
    XrmDatabase rdb,
    _Xconst char *res_name,
    _Xconst char *res_class)
{
    XOM om;

    om = Xcalloc(1, sizeof(XOMGenericRec));
    if (om == NULL)
	return (XOM) NULL;

    om->methods = &methods;
    om->core.lcd = lcd;
    om->core.display = dpy;
    om->core.rdb = rdb;
    if (res_name) {
	om->core.res_name = strdup(res_name);
	if (om->core.res_name == NULL)
	    goto err;
    }
    if (res_class) {
	om->core.res_class = strdup(res_class);
	if (om->core.res_class == NULL)
	    goto err;
    }

    if (om_resources[0].xrm_name == NULLQUARK)
	_XlcCompileResourceList(om_resources, XlcNumber(om_resources));

    om->core.resources = om_resources;
    om->core.num_resources = XlcNumber(om_resources);

    return om;

err:
    close_om(om);

    return (XOM) NULL;
}

Project: libx11
File: omGeneric.c

set_om_values(
    XOM om,
    XlcArgList args,
    int num_args)
{
    if (om->core.resources == NULL)
	return NULL;

    return _XlcSetValues((XPointer) om, om->core.resources,
			 om->core.num_resources, args, num_args, XlcSetMask);
}

Project: libx11
File: omGeneric.c

destroy_oc(
    XOC oc)
{
    Display *dpy = oc->core.om->core.display;
    XOCGenericPart *gen = XOC_GENERIC(oc);

    if (gen->mbs_to_cs)
	_XlcCloseConverter(gen->mbs_to_cs);

    if (gen->wcs_to_cs)
	_XlcCloseConverter(gen->wcs_to_cs);

    if (gen->utf8_to_cs)
	_XlcCloseConverter(gen->utf8_to_cs);

/* For VW/UDC start */ /* Change 1996.01.8 */
    destroy_fontdata(gen,dpy);
/*
*/
/* For VW/UDC end */

    Xfree(oc->core.base_name_list);
    XFreeStringList(oc->core.font_info.font_name_list);
    Xfree(oc->core.font_info.font_struct_list);
    XFreeStringList(oc->core.missing_list.charset_list);

#ifdef notdef

    Xfree(oc->core.res_name);
    Xfree(oc->core.res_class);
#endif

    Xfree(oc);
}

Project: libx11
File: omGeneric.c

load_fontdata(
    XOC		oc,
    FontData	font_data,
    int		font_data_num)
{
    Display	*dpy = oc->core.om->core.display;
    FontData	fd = font_data;

    if(font_data == NULL) return(True);
    for( ; font_data_num-- ; fd++) {
	if(fd->xlfd_name != (char *) NULL && fd->font == NULL) {
	    fd->font = XLoadQueryFont(dpy, fd->xlfd_name);
	    if (fd->font == NULL){
		return False;
	    }
	}
    }
    return True;
}

Project: libx11
File: omGeneric.c

add_data(
    XOM om)
{
    XOMGenericPart *gen = XOM_GENERIC(om);
    OMData new;
    int num;

    if ((num = gen->data_num))
        new = Xrealloc(gen->data, (num + 1) * sizeof(OMDataRec));
    else
        new = Xmalloc(sizeof(OMDataRec));

    if (new == NULL)
        return NULL;

    gen->data_num = num + 1;
    gen->data = new;

    new += num;
    bzero((char *) new, sizeof(OMDataRec));

    return new;
}

Project: libx11
File: omGeneric.c

set_missing_list(
    XOC oc)
{
    XOCGenericPart *gen = XOC_GENERIC(oc);
    FontSet font_set;
    char **charset_list, *charset_buf;
    int	count, length, font_set_num;
    int result = 1;

    font_set = gen->font_set;
    font_set_num = gen->font_set_num;
    count = length = 0;

    for ( ; font_set_num-- > 0; font_set++) {
	if (font_set->info || font_set->font) {
	    continue;
	}

	/* Change 1996.01.23 start */
	if(font_set->font_data_count <= 0 ||
	   font_set->font_data == (FontData)NULL) {
	    if(font_set->substitute_num <= 0 ||
	       font_set->substitute == (FontData)NULL) {
		if(font_set->charset_list != NULL){
		 length +=
		  strlen(font_set->charset_list[0]->encoding_name) + 1;
		} else {
		  length += 1;
		}
	    } else {
		length += strlen(font_set->substitute->name) + 1;
	    }
	} else {
	    length += strlen(font_set->font_data->name) + 1;
	}
	/* Change 1996.01.23 end */
	count++;
    }

    if (count < 1) {
	return True;
    }

    charset_list = Xmalloc(sizeof(char *) * count);
    if (charset_list == NULL) {
	return False;
    }

    charset_buf = Xmalloc(length);
    if (charset_buf == NULL) {
	Xfree(charset_list);
	return False;
    }

    oc->core.missing_list.charset_list = charset_list;
    oc->core.missing_list.charset_count = count;

    font_set = gen->font_set;
    font_set_num = gen->font_set_num;

    for ( ; font_set_num-- > 0; font_set++) {
	if (font_set->info || font_set->font) {
	    continue;
	}

	/* Change 1996.01.23 start */
	if(font_set->font_data_count <= 0 ||
	   font_set->font_data == (FontData)NULL) {
	    if(font_set->substitute_num <= 0 ||
	       font_set->substitute == (FontData)NULL) {
		if(font_set->charset_list != NULL){
		 strcpy(charset_buf,
			font_set->charset_list[0]->encoding_name);
		} else {
		 strcpy(charset_buf, "");
		}
		result = 0;
	    } else {
		strcpy(charset_buf, font_set->substitute->name);
	    }
	} else {
	    strcpy(charset_buf, font_set->font_data->name);
	}
	/* Change 1996.01.23 end */
	*charset_list++ = charset_buf;
	charset_buf += strlen(charset_buf) + 1;
    }

    if(result == 0) {
	return(False);
    }

    return True;
}

Project: libx11
File: omGeneric.c

free_fontdataOC(
    Display	*dpy,
    FontData	font_data,
    int		font_data_count)
{
    for( ; font_data_count-- ; font_data++) {
	if(font_data->xlfd_name){
	    Xfree(font_data->xlfd_name);
	    font_data->xlfd_name = NULL;
	}
	if(font_data->font){				/* ADD 1996.01.7 */
	    if(font_data->font->fid)			/* Add 1996.01.23 */
		XFreeFont(dpy,font_data->font);		/* ADD 1996.01.7 */
	    else					/* Add 1996.01.23 */
		XFreeFontInfo(NULL, font_data->font, 1);/* Add 1996.01.23 */
	    font_data->font = NULL;
	}
/*
 * font_data->name and font_data->scopes belong to the OM not OC.
 * To save space this data is shared between OM and OC. We are
 * not allowed to free it here.
 * It has been moved to free_fontdataOM()
 */
/*
	if(font_data->scopes){
	    Xfree(font_data->scopes);
	    font_data->scopes = NULL;
	}
	if(font_data->name){
	    Xfree(font_data->name);
	    font_data->name = NULL;
	}
*/
    }
}

Project: libx11
File: omGeneric.c

static void read_vw(
    XLCd    lcd,
    OMData  font_set,
    int     num)
{
    char **value, buf[BUFSIZ];
    int count;

    snprintf(buf, sizeof(buf), "fs%d.font.vertical_map", num);
    _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
    if (count > 0){
        _XlcDbg_printValue(buf,value,count);
        font_set->vmap_num = count;
        font_set->vmap = read_EncodingInfo(count,value);
    }

    snprintf(buf, sizeof(buf), "fs%d.font.vertical_rotate", num);
    _XlcGetResource(lcd, "XLC_FONTSET", buf, &value, &count);
    if (count > 0){
        _XlcDbg_printValue(buf,value,count);
        font_set->vrotate = read_vrotate(count,value,&(font_set->vrotate_type),
				&(font_set->vrotate_num));
    }
}

Project: libx11
File: omGeneric.c

load_font(
    XOC oc)
{
    XOCGenericPart *gen = XOC_GENERIC(oc);
    FontSet font_set = gen->font_set;
    int num = gen->font_set_num;

    for ( ; num-- > 0; font_set++) {
	if (font_set->font_name == NULL)
	    continue;

        if (load_fontset_data (oc, font_set) != True)
	    return False;
#ifndef TESTVERSION
	if(load_fontdata(oc, font_set->font_data,
			 font_set->font_data_count) != True)
	    return False;

	if(load_fontdata(oc, font_set->substitute,
			 font_set->substitute_num) != True)
	    return False;
#endif

/* Add 1996.05.20 */
        if( oc->core.orientation == XOMOrientation_TTB_RTL ||
            oc->core.orientation == XOMOrientation_TTB_LTR ){
	    if (font_set->vpart_initialize == 0) {
	       load_fontdata(oc, font_set->vmap, font_set->vmap_num);
	       load_fontdata(oc, (FontData) font_set->vrotate,
			 font_set->vrotate_num);
                font_set->vpart_initialize = 1;
	    }
        }

	if (font_set->font->min_byte1 || font_set->font->max_byte1)
	    font_set->is_xchar2b = True;
	else
	    font_set->is_xchar2b = False;
    }

    return True;
}

Project: libx11
File: omGeneric.c

read_EncodingInfo(
    int count,
    char **value)
{
    FontData font_data,ret;
    char *buf, *bufptr,*scp;
    int len, i;
    font_data = Xcalloc(count, sizeof(FontDataRec));
    if (font_data == NULL)
        return NULL;

    ret = font_data;
    for (i = 0; i < count; i++, font_data++) {
/*
        strcpy(buf, *value++);
*/
	buf = *value; value++;
        if ((bufptr = strchr(buf, ':'))) {
	    len = (int)(bufptr - buf);
            bufptr++ ;
	} else
            len = strlen(buf);
        font_data->name = Xmalloc(len + 1);
        if (font_data->name == NULL) {
            free_fontdataOM(ret, i + 1);
            Xfree(ret);
            return NULL;
	}
        strncpy(font_data->name, buf,len);
	font_data->name[len] = 0;
        if (bufptr && _XlcCompareISOLatin1(bufptr, "GL") == 0)
            font_data->side = XlcGL;
        else if (bufptr && _XlcCompareISOLatin1(bufptr, "GR") == 0)
            font_data->side = XlcGR;
        else
            font_data->side = XlcGLGR;

        if (bufptr && (scp = strchr(bufptr, '['))){
            font_data->scopes = _XlcParse_scopemaps(scp,&(font_data->scopes_num));
        }
    }
    return(ret);
}

Project: libx11
File: omGeneric.c

get_rotate_fontname(
    char *font_name)
{
    char *pattern = NULL, *ptr = NULL;
    char *fields[CHARSET_ENCODING_FIELD];
    char str_pixel[32], str_point[4];
    char *rotate_font_ptr = NULL;
    int pixel_size = 0;
    int field_num = 0, len = 0;

    if(font_name == (char *) NULL || (len = strlen(font_name)) <= 0
       || len > XLFD_MAX_LEN)
	return NULL;

    pattern = strdup(font_name);
    if(!pattern)
	return NULL;

    memset(fields, 0, sizeof(char *) * 14);
    ptr = pattern;
    while(isspace(*ptr)) {
	ptr++;
    }
    if(*ptr == '-')
	ptr++;

    for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD && ptr && *ptr ;
			ptr++, field_num++) {
	fields[field_num] = ptr;

	if((ptr = strchr(ptr, '-'))) {
	    *ptr = '\0';
	} else {
	    field_num++;	/* Count last field */
	    break;
	}
    }

    if(field_num < CHARSET_ENCODING_FIELD)
	goto free_pattern;

    /* Pixel Size field : fields[6] */
    for(ptr = fields[PIXEL_SIZE_FIELD - 1] ; ptr && *ptr; ptr++) {
	if(!isdigit(*ptr)) {
	    if(*ptr == '['){ /* 960730 */
	        strcpy(pattern, font_name);
		return(pattern);
	    }
	    goto free_pattern;
	}
    }
    pixel_size = atoi(fields[PIXEL_SIZE_FIELD - 1]);
    snprintf(str_pixel, sizeof(str_pixel),
	     "[ 0 ~%d %d 0 ]", pixel_size, pixel_size);
    fields[6] = str_pixel;

    /* Point Size field : fields[7] */
    strcpy(str_point, "*");
    fields[POINT_SIZE_FIELD - 1] = str_point;

    len = 0;
    for (field_num = 0; field_num < CHARSET_ENCODING_FIELD &&
			fields[field_num]; field_num++) {
	len += 1 + strlen(fields[field_num]);
    }

    /* Max XLFD length is 255 */
    if (len > XLFD_MAX_LEN)
	goto free_pattern;

    rotate_font_ptr = Xmalloc(len + 1);
    if(!rotate_font_ptr)
	goto free_pattern;

    rotate_font_ptr[0] = '\0';

    for(field_num = 0 ; field_num < CHARSET_ENCODING_FIELD &&
			fields[field_num] ; field_num++) {
	strcat(rotate_font_ptr, "-");
	strcat(rotate_font_ptr, fields[field_num]);
    }

free_pattern:
    Xfree(pattern);

    return rotate_font_ptr;
}

Project: libx11
File: omGeneric.c

parse_all_name(
    XOC		oc,
    FontData	font_data,
    char	*pattern)
{

#ifdef OLDCODE
    if(is_match_charset(font_data, pattern) != True)
 	return False;

    font_data->xlfd_name = strdup(pattern);
    if(font_data->xlfd_name == NULL)
	return (-1);

    return True;
#else  /* OLDCODE */
    Display *dpy = oc->core.om->core.display;
    char **fn_list = NULL, *prop_fname = NULL;
    int list_num;
    XFontStruct *fs_list;
    if(is_match_charset(font_data, pattern) != True) {
	/*
	 * pattern should not contain any wildcard (execpt '?')
	 * this was probably added to make this case insensitive.
	 */
	if ((fn_list = XListFontsWithInfo(dpy, pattern,
				      MAXFONTS,
				      &list_num, &fs_list)) == NULL) {
            return False;
        }
	/* shouldn't we loop here ? */
        else if ((prop_fname = get_prop_name(dpy, fs_list)) == NULL) {
            XFreeFontInfo(fn_list, fs_list, list_num);
            return False;
        }
        else if ((is_match_charset(font_data, prop_fname) != True)) {
            XFree(prop_fname);
            XFreeFontInfo(fn_list, fs_list, list_num);
            return False;
        }
        else {
	    font_data->xlfd_name = prop_fname;
            XFreeFontInfo(fn_list, fs_list, list_num);
            return True;
        }
    }

    font_data->xlfd_name = strdup(pattern);
    if(font_data->xlfd_name == NULL)
	return (-1);

    return True;
#endif /* OLDCODE */
}

Project: libx11
File: omGeneric.c

get_oc_values(
    XOC oc,
    XlcArgList args,
    int num_args)
{
    if (oc->core.resources == NULL)
	return NULL;

    return _XlcGetValues((XPointer) oc, oc->core.resources,
			 oc->core.num_resources, args, num_args, XlcGetMask);
}

Project: libx11
File: omGeneric.c

_XInitOM(
    XLCd lcd)
{
    lcd->methods->open_om = _XomGenericOpenOM;

    return True;
}

Project: libx11
File: omGeneric.c

get_font_name(
    XOC oc,
    char *pattern)
{
    char **list, *name;
    int count = 0;

    list = XListFonts(oc->core.om->core.display, pattern, 1, &count);
    if (list == NULL)
	return NULL;

    name = strdup(*list);

    XFreeFontNames(list);

    return name;
}

Project: libx11
File: omGeneric.c

load_fontset_data(
    XOC		oc,
    FontSet	font_set)
{
    Display	*dpy = oc->core.om->core.display;

    if(font_set->font_name == (char *)NULL) return False ;

   /* If font_set->font is not NULL, it contains the *best*
    * match font for this FontSet.
    * -- jjw/pma (HP)
    */
    if(font_set->font == NULL) {
       font_set->font = XLoadQueryFont(dpy, font_set->font_name);
       if (font_set->font == NULL){
		return False;
       }
    }
    return True;
}

Project: libx11
File: omGeneric.c

init_core_part(
    XOC oc)
{
    XOCGenericPart *gen = XOC_GENERIC(oc);
    FontSet font_set;
    int font_set_num;
    XFontStruct **font_struct_list;
    char **font_name_list, *font_name_buf;
    int	count, length;

    font_set = gen->font_set;
    font_set_num = gen->font_set_num;
    count = length = 0;

    for ( ; font_set_num-- > 0; font_set++) {
	if (font_set->font_name == NULL)
	    continue;

	length += strlen(font_set->font_name) + 1;

	count++;
    }
    if (count == 0)
        return False;

    font_struct_list = Xmalloc(sizeof(XFontStruct *) * count);
    if (font_struct_list == NULL)
	return False;

    font_name_list = Xmalloc(sizeof(char *) * count);
    if (font_name_list == NULL)
	goto err;

    font_name_buf = Xmalloc(length);
    if (font_name_buf == NULL)
	goto err;

    oc->core.font_info.num_font = count;
    oc->core.font_info.font_name_list = font_name_list;
    oc->core.font_info.font_struct_list = font_struct_list;

    font_set = gen->font_set;
    font_set_num = gen->font_set_num;

    for (count = 0; font_set_num-- > 0; font_set++) {
	if (font_set->font_name == NULL)
	    continue;

	font_set->id = count;
	if (font_set->font)
	    *font_struct_list++ = font_set->font;
	else
	    *font_struct_list++ = font_set->info;
	strcpy(font_name_buf, font_set->font_name);
	Xfree(font_set->font_name);
	*font_name_list++ = font_set->font_name = font_name_buf;
	font_name_buf += strlen(font_name_buf) + 1;

	count++;
    }

    set_fontset_extents(oc);

    return True;

err:

    Xfree(font_name_list);
    Xfree(font_struct_list);

    return False;
}

Project: libx11
File: omGeneric.c

free_fontdataOM(
    FontData	font_data,
    int		font_data_count)
{
    if (!font_data)
	return;

    for( ; font_data_count-- ; font_data++) {
	    Xfree(font_data->name);
	    font_data->name = NULL;
	    Xfree(font_data->scopes);
	    font_data->scopes = NULL;
    }
}

Project: libx11
File: omGeneric.c

_XomGenericOpenOM(XLCd lcd, Display *dpy, XrmDatabase rdb,
		  _Xconst char *res_name, _Xconst char *res_class)
{
    XOM om;

    om = create_om(lcd, dpy, rdb, res_name, res_class);
    if (om == NULL)
	return (XOM) NULL;

    if (init_om(om) == False)
	goto err;

    return om;

err:
    close_om(om);

    return (XOM) NULL;
}

Project: libx11
File: omGeneric.c

parse_fontdata(
    XOC		 oc,
    FontSet      font_set,
    FontData	 font_data,
    int		 font_data_count,
    char	 **name_list,
    int		 name_list_count,
    ClassType	 class,
    FontDataRec *font_data_return)
{

    char	**cur_name_list = name_list;
    char	*font_name      = (char *) NULL;
    char	*pattern        = (char *) NULL;
    int		found_num       = 0, ret = 0;
    int		count           = name_list_count;

    if(name_list == NULL || count <= 0) {
	return False;
    }

    if(font_data == NULL || font_data_count <= 0) {
	return False;
    }

    /* Loop through each font encoding defined in the "font_data" FontSet. */
    for ( ; font_data_count-- > 0; font_data++) {
	Bool	is_found = False;
	font_name = (char *) NULL;
	count = name_list_count;
	cur_name_list = name_list;

       /*
	* Loop through each font specified by the user
	* in the call to XCreateFontset().
	*/
	while (count-- > 0) {
            pattern = *cur_name_list++;
	    if (pattern == NULL || *pattern == '\0')
		continue;
#ifdef FONTDEBUG
		fprintf(stderr,"Font pattern: %s %s\n",
		pattern,font_data->name);
#endif

	    /*
	     * If the current font is fully specified (i.e., the
	     * xlfd contains no wildcards) and the font exists on
	     * the X Server, we have a match.
	     */
	    if (strchr(pattern, '*') == NULL &&
		(font_name = get_font_name(oc, pattern))) {
               /*
		* Find the full xlfd name for this font. If the font is
		* already in xlfd format, it is simply returned.  If the
		* font is an alias for another font, the xlfd of the
		* aliased font is returned.
		*/
		ret = parse_all_name(oc, font_data, font_name);
		Xfree(font_name);

                if (ret == -1)    return -1;
	        if (ret == False) continue;
               /*
		* Since there was an exact match of a fully-specified font
		* or a font alias, we can return now since the desired font
		* was found for the current font encoding for this FontSet.
		*
		* Previous implementations of this algorithm would
		* not return here. Instead, they continued searching
		* through the font encodings for this FontSet. The side-effect
		* of that behavior is you may return a "substitute" match
		* instead of an "exact" match.  We believe there should be a
		* preference on exact matches.  Therefore, as soon as we
		* find one, we bail.
		*
		* Also, previous implementations seemed to think it was
		* important to find either a primary or substitute font
		* for each Font encoding in the FontSet before returning an
		* acceptable font.  We don't believe this is necessary.
		* All the client cares about is finding a reasonable font
		* for what was passed in.  If we find an exact match,
		* there's no reason to look any further.
		*
		* -- jjw/pma (HP)
		*/
		if (font_data_return) {
		    font_data_return->xlfd_name = strdup(font_data->xlfd_name);
		    if (!font_data_return->xlfd_name) return -1;

		    font_data_return->side      = font_data->side;
		}
#ifdef FONTDEBUG
		fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name);
#endif

		return True;
	    }
	    /*
	     * If the font name is not fully specified
	     * (i.e., it has wildcards), we have more work to do.
	     * See the comments in parse_omit_name()
	     * for the list of things to do.
	     */
	    ret = parse_omit_name(oc, font_data, pattern);

            if (ret == -1)    return -1;
	    if (ret == False) continue;

           /*
	    * A font which matched the wild-carded specification was found.
	    * Only update the return data if a font has not yet been found.
	    * This maintains the convention that FontSets listed higher in
	    * a CodeSet in the Locale Database have higher priority than
	    * those FontSets listed lower in the CodeSet.  In the following
	    * example:
	    *
	    * fs1 {
	    *        charset     HP-JIS:GR
	    *        font        JISX0208.1990-0:GL;\
	    *                    JISX0208.1990-1:GR;\
	    *                    JISX0208.1983-0:GL;\
	    *                    JISX0208.1983-1:GR
	    * }
	    *
	    * a font found in the JISX0208.1990-0 FontSet will have a
	    * higher priority than a font found in the JISX0208.1983-0
	    * FontSet.
	    */
	    if (font_data_return && font_data_return->xlfd_name == NULL) {

#ifdef FONTDEBUG
		fprintf(stderr,"XLFD name: %s\n",font_data->xlfd_name);
#endif
		font_data_return->xlfd_name = strdup(font_data->xlfd_name);
                if (!font_data_return->xlfd_name) return -1;

	        font_data_return->side      = font_data->side;
	    }

	    found_num++;
	    is_found = True;

	    break;
	}

	switch(class) {
	  case C_PRIMARY:
	       if(is_found == False) {
		 /*
		  * Did not find a font for the current FontSet.  Check the
		  * FontSet's "substitute" font for a match.  If we find a
		  * match, we'll keep searching in hopes of finding an exact
		  * match later down the FontSet list.
		  *
		  * when we return and we have found a font font_data_return
		  * contains the first (ie. best) match no matter if this
		  * is a C_PRIMARY or a C_SUBSTITUTE font
		  */
		  ret = parse_fontdata(oc, font_set, font_set->substitute,
				       font_set->substitute_num, name_list,
				       name_list_count, C_SUBSTITUTE,
				       font_data_return);
                  if (ret == -1)    return -1;
		  if (ret == False) continue;

		  found_num++;
		  is_found = True;
               }
#ifdef TESTVERSION
	       else
		   return True;
#endif
	       break;

	  case C_SUBSTITUTE:
	  case C_VMAP:
	       if(is_found == True)
		  return True;
	       break;

	  case C_VROTATE:
	       if(is_found == True) {
		  char	*rotate_name;

		  if((rotate_name = get_rotate_fontname(font_data->xlfd_name))
		     != NULL) {
		      Xfree(font_data->xlfd_name);
		      font_data->xlfd_name = rotate_name;

		      return True;
		  }
		  Xfree(font_data->xlfd_name);
		  font_data->xlfd_name = NULL;
		  return False;
	       }
	       break;
	}
    }

    if(class == C_PRIMARY && found_num >= 1)
	return True;

    return False;
}