Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 428 lines (334 sloc) 9.063 kb
e310e5f - more memory allocation integer overflow auditing
Tony Cook authored
1 #include "imager.h"
50c7538 Move freetype 2 support into its own module
Tony Cook authored
2 #include "imageri.h"
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
3 #include <stdlib.h>
4 #ifndef _MSC_VER
5 #include <unistd.h>
6 #endif
7
8
9 /* FIXME: make allocation dynamic */
10
11
12 #ifdef IMAGER_DEBUG_MALLOC
13
2ff8ed3 Added more logging to quant.c. Removed global variables from gif.c.
Arnar Mar Hrafnkelsson authored
14 #define MAXMAL 102400
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
15 #define MAXDESC 65
16
a743c0a Removed a bunch of unused variables and fixed an attempt to print out a
Arnar Mar Hrafnkelsson authored
17 #define UNDRRNVAL 10
18 #define OVERRNVAL 10
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
19
20 #define PADBYTE 0xaa
21
22
23 static int malloc_need_init = 1;
24
25 typedef struct {
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
26 void* ptr;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
27 size_t size;
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
28 char comm[MAXDESC];
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
29 } malloc_entry;
30
31 malloc_entry malloc_pointers[MAXMAL];
32
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
33
34
35
36 /* Utility functions */
37
38
39 static
40 void
aea697a fix errors and some warnings on Win32
Tony Cook authored
41 malloc_init(void) {
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
42 int i;
43 for(i=0; i<MAXMAL; i++) malloc_pointers[i].ptr = NULL;
44 malloc_need_init = 0;
45 atexit(malloc_state);
46 }
47
48
49 static
50 int
51 find_ptr(void *p) {
52 int i;
53 for(i=0;i<MAXMAL;i++)
54 if (malloc_pointers[i].ptr == p)
55 return i;
56 return -1;
57 }
58
59
60 /* Takes a pointer to real start of array,
61 * sets the entries in the table, returns
62 * the offset corrected pointer */
63
64 static
65 void *
66 set_entry(int i, char *buf, size_t size, char *file, int line) {
67 memset( buf, PADBYTE, UNDRRNVAL );
68 memset( &buf[UNDRRNVAL+size], PADBYTE, OVERRNVAL );
69 buf += UNDRRNVAL;
70 malloc_pointers[i].ptr = buf;
71 malloc_pointers[i].size = size;
86c8d19 @tonycoz [rt #69147] detect and use snprintf() more
authored
72 #ifdef IMAGER_SNPRINTF
73 snprintf(malloc_pointers[i].comm, sizeof(malloc_pointers[i].comm),
74 "%s (%d)", file, line);
75 #else
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
76 sprintf(malloc_pointers[i].comm,"%s (%d)", file, line);
86c8d19 @tonycoz [rt #69147] detect and use snprintf() more
authored
77 #endif
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
78 return buf;
79 }
80
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
81 void
aea697a fix errors and some warnings on Win32
Tony Cook authored
82 malloc_state(void) {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
83 int i;
84 size_t total = 0;
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
85
cd4b0b2 have error.c free a non-leak when using the debug malloc
Tony Cook authored
86 i_clear_error();
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
87 mm_log((0,"malloc_state()\n"));
88 bndcheck_all();
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
89 for(i=0; i<MAXMAL; i++) if (malloc_pointers[i].ptr != NULL) {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
90 mm_log((0,"%d: %lu (%p) : %s\n", i, (unsigned long)malloc_pointers[i].size, malloc_pointers[i].ptr, malloc_pointers[i].comm));
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
91 total += malloc_pointers[i].size;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
92 }
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
93 if (total == 0) mm_log((0,"No memory currently used!\n"))
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
94 else mm_log((0,"total: %lu\n", (unsigned long)total));
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
95 }
96
97
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
98
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
99 void*
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
100 mymalloc_file_line(size_t size, char* file, int line) {
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
101 char *buf;
102 int i;
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
103 if (malloc_need_init) malloc_init();
104
105 /* bndcheck_all(); Uncomment for LOTS OF THRASHING */
106
107 if ( (i = find_ptr(NULL)) < 0 ) {
108 mm_log((0,"more than %d segments allocated at %s (%d)\n", MAXMAL, file, line));
109 exit(3);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
110 }
111
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
112 if ( (buf = malloc(size+UNDRRNVAL+OVERRNVAL)) == NULL ) {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
113 mm_log((1,"Unable to allocate %ld for %s (%i)\n", (long)size, file, line));
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
114 exit(3);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
115 }
116
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
117 buf = set_entry(i, buf, size, file, line);
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
118 mm_log((1,"mymalloc_file_line: slot <%d> %ld bytes allocated at %p for %s (%d)\n", i, (long)size, buf, file, line));
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
119 return buf;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
120 }
121
e310e5f - more memory allocation integer overflow auditing
Tony Cook authored
122 void *
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
123 (mymalloc)(size_t size) {
e310e5f - more memory allocation integer overflow auditing
Tony Cook authored
124 return mymalloc_file_line(size, "unknown", 0);
125 }
126
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
127 void*
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
128 myrealloc_file_line(void *ptr, size_t newsize, char* file, int line) {
129 char *buf;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
130 int i;
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
131
132 if (malloc_need_init) malloc_init();
133 /* bndcheck_all(); ACTIVATE FOR LOTS OF THRASHING */
134
135 if (!ptr) {
136 mm_log((1, "realloc called with ptr = NULL, sending request to malloc\n"));
137 return mymalloc_file_line(newsize, file, line);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
138 }
139
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
140 if (!newsize) {
141 mm_log((1, "newsize = 0, sending request to free\n"));
142 myfree_file_line(ptr, file, line);
143 return NULL;
144 }
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
145
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
146 if ( (i = find_ptr(ptr)) == -1) {
147 mm_log((0, "Unable to find %p in realloc for %s (%i)\n", ptr, file, line));
148 exit(3);
149 }
150
aea697a fix errors and some warnings on Win32
Tony Cook authored
151 if ( (buf = realloc(((char *)ptr)-UNDRRNVAL, UNDRRNVAL+OVERRNVAL+newsize)) == NULL ) {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
152 mm_log((1,"Unable to reallocate %ld bytes at %p for %s (%i)\n", (long)
153 newsize, ptr, file, line));
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
154 exit(3);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
155 }
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
156
157 buf = set_entry(i, buf, newsize, file, line);
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
158 mm_log((1,"realloc_file_line: slot <%d> %ld bytes allocated at %p for %s (%d)\n", i, (long)newsize, buf, file, line));
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
159 return buf;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
160 }
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
161
e310e5f - more memory allocation integer overflow auditing
Tony Cook authored
162 void *
163 (myrealloc)(void *ptr, size_t newsize) {
164 return myrealloc_file_line(ptr, newsize, "unknown", 0);
165 }
166
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
167 static
168 void
169 bndcheck(int idx) {
170 int i;
171 size_t s = malloc_pointers[idx].size;
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
172 unsigned char *pp = malloc_pointers[idx].ptr;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
173 if (!pp) {
174 mm_log((1, "bndcheck: No pointer in slot %d\n", idx));
175 return;
176 }
177
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
178 for(i=0;i<UNDRRNVAL;i++) {
179 if (pp[-(1+i)] != PADBYTE)
180 mm_log((1,"bndcheck: UNDERRUN OF %d bytes detected: slot = %d, point = %p, size = %ld\n", i+1, idx, pp, (long)s ));
181 }
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
182
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
183 for(i=0;i<OVERRNVAL;i++) {
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
184 if (pp[s+i] != PADBYTE)
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
185 mm_log((1,"bndcheck: OVERRUN OF %d bytes detected: slot = %d, point = %p, size = %ld\n", i+1, idx, pp, (long)s ));
186 }
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
187 }
188
189 void
190 bndcheck_all() {
191 int idx;
192 mm_log((1, "bndcheck_all()\n"));
76ff75b tga.c should now support reading/writing all variants of targa files.…
Arnar Mar Hrafnkelsson authored
193 for(idx=0; idx<MAXMAL; idx++)
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
194 if (malloc_pointers[idx].ptr)
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
195 bndcheck(idx);
196 }
197
198 void
199 myfree_file_line(void *p, char *file, int line) {
200 char *pp = p;
201 int match = 0;
202 int i;
e2f09cf myfree_file_line no longer treats freeing a NULL pointer as an error
Tony Cook authored
203
204 if (p == NULL)
205 return;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
206
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
207 for(i=0; i<MAXMAL; i++) if (malloc_pointers[i].ptr == p) {
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
208 mm_log((1,"myfree_file_line: pointer %i (%s) freed at %s (%i)\n", i, malloc_pointers[i].comm, file, line));
209 bndcheck(i);
fe6163b Various Changes to the memory accounting code, myrealloc() added.
Arnar Mar Hrafnkelsson authored
210 malloc_pointers[i].ptr = NULL;
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
211 match++;
212 }
97c4eff merge write to gif tags updates
Tony Cook authored
213
214 mm_log((1, "myfree_file_line: freeing address %p (real %p)\n", pp, pp-UNDRRNVAL));
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
215
216 if (match != 1) {
f1ac502 support for generic fills for box and arc, with solid, hatched
Tony Cook authored
217 mm_log((1, "myfree_file_line: INCONSISTENT REFCOUNT %d at %s (%i)\n", match, file, line));
aea697a fix errors and some warnings on Win32
Tony Cook authored
218 fprintf(stderr, "myfree_file_line: INCONSISTENT REFCOUNT %d at %s (%i)\n", match, file, line);
a73aeb5 Fixed most outstanding memory leaks that are revealed in the test cases.
Arnar Mar Hrafnkelsson authored
219 exit(255);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
220 }
221
222
223 free(pp-UNDRRNVAL);
224 }
225
e310e5f - more memory allocation integer overflow auditing
Tony Cook authored
226 void
227 (myfree)(void *block) {
228 myfree_file_line(block, "unknown", 0);
229 }
230
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
231 #else
232
233 void
234 malloc_state() {
235 }
236
237 void*
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
238 mymalloc(size_t size) {
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
239 void *buf;
240
a659442 - eliminate unused variables and static functions
Tony Cook authored
241 if (size < 0) {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
242 fprintf(stderr, "Attempt to allocate size %ld\n", (long)size);
a659442 - eliminate unused variables and static functions
Tony Cook authored
243 exit(3);
244 }
245
a743c0a Removed a bunch of unused variables and fixed an attempt to print out a
Arnar Mar Hrafnkelsson authored
246 if ( (buf = malloc(size)) == NULL ) {
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
247 mm_log((1, "mymalloc: unable to malloc %ld\n", (long)size));
248 fprintf(stderr,"Unable to malloc %ld.\n", (long)size); exit(3);
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
249 }
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
250 mm_log((1, "mymalloc(size %ld) -> %p\n", (long)size, buf));
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
251 return buf;
252 }
253
e310e5f - more memory allocation integer overflow auditing
Tony Cook authored
254 void *
255 mymalloc_file_line(size_t size, char *file, int line) {
256 return mymalloc(size);
257 }
258
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
259 void
260 myfree(void *p) {
dd55acc Switched all of jpeg to iolayer functions, removed older functions an…
Arnar Mar Hrafnkelsson authored
261 mm_log((1, "myfree(p %p)\n", p));
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
262 free(p);
263 }
264
e310e5f - more memory allocation integer overflow auditing
Tony Cook authored
265 void
266 myfree_file_line(void *p, char *file, int line) {
267 myfree(p);
268 }
269
faa9b3e Egads
Tony Cook authored
270 void *
271 myrealloc(void *block, size_t size) {
272 void *result;
273
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
274 mm_log((1, "myrealloc(block %p, size %ld)\n", block, (long)size));
faa9b3e Egads
Tony Cook authored
275 if ((result = realloc(block, size)) == NULL) {
276 mm_log((1, "myrealloc: out of memory\n"));
277 fprintf(stderr, "Out of memory.\n");
278 exit(3);
279 }
280 return result;
281 }
282
e310e5f - more memory allocation integer overflow auditing
Tony Cook authored
283 void *
284 myrealloc_file_line(void *block, size_t newsize, char *file, int size) {
285 return myrealloc(block, newsize);
286 }
287
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
288 #endif /* IMAGER_MALLOC_DEBUG */
289
290
291
292
8047cbb Added memory pools to make clean up of temporary buffers simpler.
Arnar Mar Hrafnkelsson authored
293 /* memory pool implementation */
294
295 void
296 i_mempool_init(i_mempool *mp) {
297 mp->alloc = 10;
298 mp->used = 0;
299 mp->p = mymalloc(sizeof(void*)*mp->alloc);
300 }
301
302 void
303 i_mempool_extend(i_mempool *mp) {
304 mp->p = myrealloc(mp->p, mp->alloc * 2);
305 mp->alloc *=2;
306 }
307
308 void *
309 i_mempool_alloc(i_mempool *mp, size_t size) {
310 if (mp->used == mp->alloc) i_mempool_extend(mp);
311 mp->p[mp->used] = mymalloc(size);
312 mp->used++;
313 return mp->p[mp->used-1];
314 }
315
316
317 void
318 i_mempool_destroy(i_mempool *mp) {
319 unsigned int i;
320 for(i=0; i<mp->used; i++) myfree(mp->p[i]);
321 myfree(mp->p);
322 }
323
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
324
325
5473b91 Cleaned up io.h, io.c which had functions not used any more, removed …
Arnar Mar Hrafnkelsson authored
326 /* Should these really be here? */
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
327
328 #undef min
329 #undef max
330
50c7538 Move freetype 2 support into its own module
Tony Cook authored
331 i_img_dim
332 i_minx(i_img_dim a, i_img_dim b) {
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
333 if (a<b) return a; else return b;
334 }
335
50c7538 Move freetype 2 support into its own module
Tony Cook authored
336 i_img_dim
337 i_maxx(i_img_dim a, i_img_dim b) {
02d1d62 Initial revision
Arnar Mar Hrafnkelsson authored
338 if (a>b) return a; else return b;
339 }
340
4f68b48 support UTF with Freetype 1.x
Tony Cook authored
341
342 struct utf8_size {
343 int mask, expect;
344 int size;
345 };
346
347 struct utf8_size utf8_sizes[] =
348 {
349 { 0x80, 0x00, 1 },
350 { 0xE0, 0xC0, 2 },
351 { 0xF0, 0xE0, 3 },
352 { 0xF8, 0xF0, 4 },
353 };
354
355 /*
50c7538 Move freetype 2 support into its own module
Tony Cook authored
356 =item i_utf8_advance(char **p, size_t *len)
4f68b48 support UTF with Freetype 1.x
Tony Cook authored
357
50c7538 Move freetype 2 support into its own module
Tony Cook authored
358 Retrieve a C<UTF-8> character from the stream.
4f68b48 support UTF with Freetype 1.x
Tony Cook authored
359
360 Modifies *p and *len to indicate the consumed characters.
361
50c7538 Move freetype 2 support into its own module
Tony Cook authored
362 This doesn't support the extended C<UTF-8> encoding used by later
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
363 versions of Perl. Since this is typically used to implement text
364 output by font drivers, the strings supplied shouldn't have such out
365 of range characters.
4f68b48 support UTF with Freetype 1.x
Tony Cook authored
366
50c7538 Move freetype 2 support into its own module
Tony Cook authored
367 This doesn't check that the C<UTF-8> character is using the shortest
855fe4d break out of the search loop early when we find the right utf8 code
Tony Cook authored
368 possible representation.
369
8d14daa @tonycoz switch to using size_t and i_img_dim strictly
authored
370 Returns ~0UL on failure.
371
4f68b48 support UTF with Freetype 1.x
Tony Cook authored
372 =cut
373 */
374
855fe4d break out of the search loop early when we find the right utf8 code
Tony Cook authored
375 unsigned long
718b8c9 move win32 font support in a new directory, and use Imager::Probe
Tony Cook authored
376 i_utf8_advance(char const **p, size_t *len) {
4f68b48 support UTF with Freetype 1.x
Tony Cook authored
377 unsigned char c;
378 int i, ci, clen = 0;
379 unsigned char codes[3];
380 if (*len == 0)
381 return ~0UL;
382 c = *(*p)++; --*len;
383
384 for (i = 0; i < sizeof(utf8_sizes)/sizeof(*utf8_sizes); ++i) {
385 if ((c & utf8_sizes[i].mask) == utf8_sizes[i].expect) {
386 clen = utf8_sizes[i].size;
855fe4d break out of the search loop early when we find the right utf8 code
Tony Cook authored
387 break;
4f68b48 support UTF with Freetype 1.x
Tony Cook authored
388 }
389 }
390 if (clen == 0 || *len < clen-1) {
391 --*p; ++*len;
392 return ~0UL;
393 }
394
395 /* check that each character is well formed */
396 i = 1;
397 ci = 0;
398 while (i < clen) {
399 if (((*p)[ci] & 0xC0) != 0x80) {
400 --*p; ++*len;
401 return ~0UL;
402 }
403 codes[ci] = (*p)[ci];
404 ++ci; ++i;
405 }
406 *p += clen-1; *len -= clen-1;
407 if (c & 0x80) {
408 if ((c & 0xE0) == 0xC0) {
409 return ((c & 0x1F) << 6) + (codes[0] & 0x3F);
410 }
411 else if ((c & 0xF0) == 0xE0) {
412 return ((c & 0x0F) << 12) | ((codes[0] & 0x3F) << 6) | (codes[1] & 0x3f);
413 }
414 else if ((c & 0xF8) == 0xF0) {
415 return ((c & 0x07) << 18) | ((codes[0] & 0x3F) << 12)
416 | ((codes[1] & 0x3F) << 6) | (codes[2] & 0x3F);
417 }
418 else {
419 *p -= clen; *len += clen;
420 return ~0UL;
421 }
422 }
423 else {
424 return c;
425 }
426 }
427
Something went wrong with that request. Please try again.