rune.c revision 71579
1/*-
2 * Copyright (c) 1993
3 *	The Regents of the University of California.  All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Paul Borman at Krystal Technologies.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by the University of
19 *	California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 *    may be used to endorse or promote products derived from this software
22 *    without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * $FreeBSD: head/lib/libc/locale/rune.c 71579 2001-01-24 13:01:12Z deischen $
37 */
38
39#if defined(LIBC_SCCS) && !defined(lint)
40static char sccsid[] = "@(#)rune.c	8.1 (Berkeley) 6/4/93";
41#endif /* LIBC_SCCS and not lint */
42
43#include "namespace.h"
44#include <rune.h>
45#include <stdio.h>
46#include <string.h>
47#include <stdlib.h>
48#include <sys/types.h>
49#include <sys/stat.h>
50#include "un-namespace.h"
51
52_RuneLocale *
53_Read_RuneMagi(fp)
54	FILE *fp;
55{
56	char *data;
57	void *lastp;
58	_RuneLocale *rl;
59	_RuneEntry *rr;
60	struct stat sb;
61	int x;
62
63	if (_fstat(fileno(fp), &sb) < 0)
64		return(0);
65
66	if (sb.st_size < sizeof(_RuneLocale))
67		return(0);
68
69	if ((data = malloc(sb.st_size)) == NULL)
70		return(0);
71
72	rewind(fp); /* Someone might have read the magic number once already */
73
74	if (fread(data, sb.st_size, 1, fp) != 1) {
75		free(data);
76		return(0);
77	}
78
79	rl = (_RuneLocale *)data;
80	lastp = data + sb.st_size;
81
82	rl->variable = rl + 1;
83
84	if (memcmp(rl->magic, _RUNE_MAGIC_1, sizeof(rl->magic))) {
85		free(data);
86		return(0);
87	}
88
89	rl->invalid_rune = ntohl(rl->invalid_rune);
90	rl->variable_len = ntohl(rl->variable_len);
91	rl->runetype_ext.nranges = ntohl(rl->runetype_ext.nranges);
92	rl->maplower_ext.nranges = ntohl(rl->maplower_ext.nranges);
93	rl->mapupper_ext.nranges = ntohl(rl->mapupper_ext.nranges);
94
95	for (x = 0; x < _CACHED_RUNES; ++x) {
96		rl->runetype[x] = ntohl(rl->runetype[x]);
97		rl->maplower[x] = ntohl(rl->maplower[x]);
98		rl->mapupper[x] = ntohl(rl->mapupper[x]);
99	}
100
101	rl->runetype_ext.ranges = (_RuneEntry *)rl->variable;
102	rl->variable = rl->runetype_ext.ranges + rl->runetype_ext.nranges;
103	if (rl->variable > lastp) {
104		free(data);
105		return(0);
106	}
107
108	rl->maplower_ext.ranges = (_RuneEntry *)rl->variable;
109	rl->variable = rl->maplower_ext.ranges + rl->maplower_ext.nranges;
110	if (rl->variable > lastp) {
111		free(data);
112		return(0);
113	}
114
115	rl->mapupper_ext.ranges = (_RuneEntry *)rl->variable;
116	rl->variable = rl->mapupper_ext.ranges + rl->mapupper_ext.nranges;
117	if (rl->variable > lastp) {
118		free(data);
119		return(0);
120	}
121
122	for (x = 0; x < rl->runetype_ext.nranges; ++x) {
123		rr = rl->runetype_ext.ranges;
124
125		rr[x].min = ntohl(rr[x].min);
126		rr[x].max = ntohl(rr[x].max);
127		if ((rr[x].map = ntohl(rr[x].map)) == 0) {
128			int len = rr[x].max - rr[x].min + 1;
129			rr[x].types = rl->variable;
130			rl->variable = rr[x].types + len;
131			if (rl->variable > lastp) {
132				free(data);
133				return(0);
134			}
135			while (len-- > 0)
136				rr[x].types[len] = ntohl(rr[x].types[len]);
137		} else
138			rr[x].types = 0;
139	}
140
141	for (x = 0; x < rl->maplower_ext.nranges; ++x) {
142		rr = rl->maplower_ext.ranges;
143
144		rr[x].min = ntohl(rr[x].min);
145		rr[x].max = ntohl(rr[x].max);
146		rr[x].map = ntohl(rr[x].map);
147	}
148
149	for (x = 0; x < rl->mapupper_ext.nranges; ++x) {
150		rr = rl->mapupper_ext.ranges;
151
152		rr[x].min = ntohl(rr[x].min);
153		rr[x].max = ntohl(rr[x].max);
154		rr[x].map = ntohl(rr[x].map);
155	}
156	if (((char *)rl->variable) + rl->variable_len > (char *)lastp) {
157		free(data);
158		return(0);
159	}
160
161	/*
162	 * Go out and zero pointers that should be zero.
163	 */
164	if (!rl->variable_len)
165		rl->variable = 0;
166
167	if (!rl->runetype_ext.nranges)
168		rl->runetype_ext.ranges = 0;
169
170	if (!rl->maplower_ext.nranges)
171		rl->maplower_ext.ranges = 0;
172
173	if (!rl->mapupper_ext.nranges)
174		rl->mapupper_ext.ranges = 0;
175
176	return(rl);
177}
178