]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libc/iconv/citrus_memstream.h
Fix kernel memory disclosure with nested jails.
[FreeBSD/FreeBSD.git] / lib / libc / iconv / citrus_memstream.h
1 /* $FreeBSD$ */
2 /* $NetBSD: citrus_memstream.h,v 1.3 2005/05/14 17:55:42 tshiozak Exp $ */
3
4 /*-
5  * SPDX-License-Identifier: BSD-2-Clause
6  *
7  * Copyright (c)2003 Citrus Project,
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  *
31  */
32
33 #ifndef _CITRUS_MEMSTREAM_H_
34 #define _CITRUS_MEMSTREAM_H_
35
36 struct _citrus_memory_stream {
37         struct _citrus_region   ms_region;
38         size_t                  ms_pos;
39 };
40
41 __BEGIN_DECLS
42 const char      *_citrus_memory_stream_getln(
43                     struct _citrus_memory_stream * __restrict,
44                     size_t * __restrict);
45 const char      *_citrus_memory_stream_matchline(
46                     struct _citrus_memory_stream * __restrict,
47                     const char * __restrict, size_t * __restrict, int);
48 void            *_citrus_memory_stream_chr(struct _citrus_memory_stream *,
49                     struct _citrus_region *, char);
50 void            _citrus_memory_stream_skip_ws(struct _citrus_memory_stream *);
51 __END_DECLS
52
53 static __inline int
54 _citrus_memory_stream_iseof(struct _citrus_memory_stream *ms)
55 {
56
57         return (ms->ms_pos >= _citrus_region_size(&ms->ms_region));
58 }
59
60 static __inline void
61 _citrus_memory_stream_bind(struct _citrus_memory_stream * __restrict ms,
62     const struct _citrus_region * __restrict r)
63 {
64
65         ms->ms_region = *r;
66         ms->ms_pos = 0;
67 }
68
69 static __inline void
70 _citrus_memory_stream_bind_ptr(struct _citrus_memory_stream * __restrict ms,
71     void *ptr, size_t sz)
72 {
73         struct _citrus_region r;
74
75         _citrus_region_init(&r, ptr, sz);
76         _citrus_memory_stream_bind(ms, &r);
77 }
78
79 static __inline void
80 _citrus_memory_stream_rewind(struct _citrus_memory_stream *ms)
81 {
82
83         ms->ms_pos = 0;
84 }
85
86 static __inline size_t
87 _citrus_memory_stream_tell(struct _citrus_memory_stream *ms)
88 {
89
90         return (ms->ms_pos);
91 }
92
93 static __inline size_t
94 _citrus_memory_stream_remainder(struct _citrus_memory_stream *ms)
95 {
96         size_t sz;
97
98         sz = _citrus_region_size(&ms->ms_region);
99         if (ms->ms_pos>sz)
100                 return (0);
101         return (sz-ms->ms_pos);
102 }
103
104 static __inline int
105 _citrus_memory_stream_seek(struct _citrus_memory_stream *ms, size_t pos, int w)
106 {
107         size_t sz;
108
109         sz = _citrus_region_size(&ms->ms_region);
110
111         switch (w) {
112         case SEEK_SET:
113                 if (pos >= sz)
114                         return (-1);
115                 ms->ms_pos = pos;
116                 break;
117         case SEEK_CUR:
118                 pos += (ssize_t)ms->ms_pos;
119                 if (pos >= sz)
120                         return (-1);
121                 ms->ms_pos = pos;
122                 break;
123         case SEEK_END:
124                 if (sz < pos)
125                         return (-1);
126                 ms->ms_pos = sz - pos;
127                 break;
128         }
129         return (0);
130 }
131
132 static __inline int
133 _citrus_memory_stream_getc(struct _citrus_memory_stream *ms)
134 {
135
136         if (_citrus_memory_stream_iseof(ms))
137                 return (EOF);
138         return (_citrus_region_peek8(&ms->ms_region, ms->ms_pos++));
139 }
140
141 static __inline void
142 _citrus_memory_stream_ungetc(struct _citrus_memory_stream *ms, int ch)
143 {
144
145         if (ch != EOF && ms->ms_pos > 0)
146                 ms->ms_pos--;
147 }
148
149 static __inline int
150 _citrus_memory_stream_peek(struct _citrus_memory_stream *ms)
151 {
152
153         if (_citrus_memory_stream_iseof(ms))
154                 return (EOF);
155         return (_citrus_region_peek8(&ms->ms_region, ms->ms_pos));
156 }
157
158 static __inline void *
159 _citrus_memory_stream_getregion(struct _citrus_memory_stream *ms,
160     struct _citrus_region *r, size_t sz)
161 {
162         void *ret;
163
164         if (ms->ms_pos + sz > _citrus_region_size(&ms->ms_region))
165                 return (NULL);
166
167         ret = _citrus_region_offset(&ms->ms_region, ms->ms_pos);
168         ms->ms_pos += sz;
169         if (r)
170                 _citrus_region_init(r, ret, sz);
171
172         return (ret);
173 }
174
175 static __inline int
176 _citrus_memory_stream_get8(struct _citrus_memory_stream *ms, uint8_t *rval)
177 {
178
179         if (ms->ms_pos + 1 > _citrus_region_size(&ms->ms_region))
180                 return (-1);
181
182         *rval = _citrus_region_peek8(&ms->ms_region, ms->ms_pos);
183         ms->ms_pos += 2;
184
185         return (0);
186 }
187
188 static __inline int
189 _citrus_memory_stream_get16(struct _citrus_memory_stream *ms, uint16_t *rval)
190 {
191
192         if (ms->ms_pos + 2 > _citrus_region_size(&ms->ms_region))
193                 return (-1);
194
195         *rval = _citrus_region_peek16(&ms->ms_region, ms->ms_pos);
196         ms->ms_pos += 2;
197
198         return (0);
199 }
200
201 static __inline int
202 _citrus_memory_stream_get32(struct _citrus_memory_stream *ms, uint32_t *rval)
203 {
204
205         if (ms->ms_pos + 4 > _citrus_region_size(&ms->ms_region))
206                 return (-1);
207
208         *rval = _citrus_region_peek32(&ms->ms_region, ms->ms_pos);
209         ms->ms_pos += 4;
210
211         return (0);
212 }
213
214 static __inline int
215 _citrus_memory_stream_getln_region(struct _citrus_memory_stream *ms,
216     struct _citrus_region *r)
217 {
218         const char *ptr;
219         size_t sz;
220
221         ptr = _citrus_memory_stream_getln(ms, &sz);
222         if (ptr)
223                 _citrus_region_init(r, __DECONST(void *, ptr), sz);
224
225         return (ptr == NULL);
226 }
227
228 #endif