chiark / gitweb /
eglibc (2.11.3-4+deb6u3) squeeze-lts; urgency=medium
[eglibc.git] / iconv / gconv_simple.c
1 /* Simple transformations functions.
2    Copyright (C) 1997-2005, 2007, 2008, 2009 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #include <byteswap.h>
22 #include <dlfcn.h>
23 #include <endian.h>
24 #include <errno.h>
25 #include <gconv.h>
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <wchar.h>
30 #include <sys/param.h>
31 #include <gconv_int.h>
32
33 #define BUILTIN_ALIAS(s1, s2) /* nothing */
34 #define BUILTIN_TRANSFORMATION(From, To, Cost, Name, Fct, BtowcFct, \
35                                MinF, MaxF, MinT, MaxT) \
36   extern int Fct (struct __gconv_step *, struct __gconv_step_data *,          \
37                   __const unsigned char **, __const unsigned char *,          \
38                   unsigned char **, size_t *, int, int);
39 #include "gconv_builtin.h"
40
41
42 #ifndef EILSEQ
43 # define EILSEQ EINVAL
44 #endif
45
46
47 /* Specialized conversion function for a single byte to INTERNAL, recognizing
48    only ASCII characters.  */
49 wint_t
50 __gconv_btwoc_ascii (struct __gconv_step *step, unsigned char c)
51 {
52   if (c < 0x80)
53     return c;
54   else
55     return WEOF;
56 }
57
58
59 /* Transform from the internal, UCS4-like format, to UCS4.  The
60    difference between the internal ucs4 format and the real UCS4
61    format is, if any, the endianess.  The Unicode/ISO 10646 says that
62    unless some higher protocol specifies it differently, the byte
63    order is big endian.*/
64 #define DEFINE_INIT             0
65 #define DEFINE_FINI             0
66 #define MIN_NEEDED_FROM         4
67 #define MIN_NEEDED_TO           4
68 #define FROM_DIRECTION          1
69 #define FROM_LOOP               internal_ucs4_loop
70 #define TO_LOOP                 internal_ucs4_loop /* This is not used.  */
71 #define FUNCTION_NAME           __gconv_transform_internal_ucs4
72
73
74 static inline int
75 __attribute ((always_inline))
76 internal_ucs4_loop (struct __gconv_step *step,
77                     struct __gconv_step_data *step_data,
78                     const unsigned char **inptrp, const unsigned char *inend,
79                     unsigned char **outptrp, unsigned char *outend,
80                     size_t *irreversible)
81 {
82   const unsigned char *inptr = *inptrp;
83   unsigned char *outptr = *outptrp;
84   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
85   int result;
86
87 #if __BYTE_ORDER == __LITTLE_ENDIAN
88   /* Sigh, we have to do some real work.  */
89   size_t cnt;
90   uint32_t *outptr32 = (uint32_t *) outptr;
91
92   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
93     *outptr32++ = bswap_32 (*(const uint32_t *) inptr);
94
95   *inptrp = inptr;
96   *outptrp = (unsigned char *) outptr32;
97 #elif __BYTE_ORDER == __BIG_ENDIAN
98   /* Simply copy the data.  */
99   *inptrp = inptr + n_convert * 4;
100   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
101 #else
102 # error "This endianess is not supported."
103 #endif
104
105   /* Determine the status.  */
106   if (*inptrp == inend)
107     result = __GCONV_EMPTY_INPUT;
108   else if (*outptrp + 4 > outend)
109     result = __GCONV_FULL_OUTPUT;
110   else
111     result = __GCONV_INCOMPLETE_INPUT;
112
113   return result;
114 }
115
116 #ifndef _STRING_ARCH_unaligned
117 static inline int
118 __attribute ((always_inline))
119 internal_ucs4_loop_unaligned (struct __gconv_step *step,
120                               struct __gconv_step_data *step_data,
121                               const unsigned char **inptrp,
122                               const unsigned char *inend,
123                               unsigned char **outptrp, unsigned char *outend,
124                               size_t *irreversible)
125 {
126   const unsigned char *inptr = *inptrp;
127   unsigned char *outptr = *outptrp;
128   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
129   int result;
130
131 # if __BYTE_ORDER == __LITTLE_ENDIAN
132   /* Sigh, we have to do some real work.  */
133   size_t cnt;
134
135   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
136     {
137       outptr[0] = inptr[3];
138       outptr[1] = inptr[2];
139       outptr[2] = inptr[1];
140       outptr[3] = inptr[0];
141     }
142
143   *inptrp = inptr;
144   *outptrp = outptr;
145 # elif __BYTE_ORDER == __BIG_ENDIAN
146   /* Simply copy the data.  */
147   *inptrp = inptr + n_convert * 4;
148   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
149 # else
150 #  error "This endianess is not supported."
151 # endif
152
153   /* Determine the status.  */
154   if (*inptrp == inend)
155     result = __GCONV_EMPTY_INPUT;
156   else if (*outptrp + 4 > outend)
157     result = __GCONV_FULL_OUTPUT;
158   else
159     result = __GCONV_INCOMPLETE_INPUT;
160
161   return result;
162 }
163 #endif
164
165
166 static inline int
167 __attribute ((always_inline))
168 internal_ucs4_loop_single (struct __gconv_step *step,
169                            struct __gconv_step_data *step_data,
170                            const unsigned char **inptrp,
171                            const unsigned char *inend,
172                            unsigned char **outptrp, unsigned char *outend,
173                            size_t *irreversible)
174 {
175   mbstate_t *state = step_data->__statep;
176   size_t cnt = state->__count & 7;
177
178   while (*inptrp < inend && cnt < 4)
179     state->__value.__wchb[cnt++] = *(*inptrp)++;
180
181   if (__builtin_expect (cnt < 4, 0))
182     {
183       /* Still not enough bytes.  Store the ones in the input buffer.  */
184       state->__count &= ~7;
185       state->__count |= cnt;
186
187       return __GCONV_INCOMPLETE_INPUT;
188     }
189
190 #if __BYTE_ORDER == __LITTLE_ENDIAN
191   (*outptrp)[0] = state->__value.__wchb[3];
192   (*outptrp)[1] = state->__value.__wchb[2];
193   (*outptrp)[2] = state->__value.__wchb[1];
194   (*outptrp)[3] = state->__value.__wchb[0];
195
196 #elif __BYTE_ORDER == __BIG_ENDIAN
197   /* XXX unaligned */
198   (*outptrp)[0] = state->__value.__wchb[0];
199   (*outptrp)[1] = state->__value.__wchb[1];
200   (*outptrp)[2] = state->__value.__wchb[2];
201   (*outptrp)[3] = state->__value.__wchb[3];
202 #else
203 # error "This endianess is not supported."
204 #endif
205   *outptrp += 4;
206
207   /* Clear the state buffer.  */
208   state->__count &= ~7;
209
210   return __GCONV_OK;
211 }
212
213 #include <iconv/skeleton.c>
214
215
216 /* Transform from UCS4 to the internal, UCS4-like format.  Unlike
217    for the other direction we have to check for correct values here.  */
218 #define DEFINE_INIT             0
219 #define DEFINE_FINI             0
220 #define MIN_NEEDED_FROM         4
221 #define MIN_NEEDED_TO           4
222 #define FROM_DIRECTION          1
223 #define FROM_LOOP               ucs4_internal_loop
224 #define TO_LOOP                 ucs4_internal_loop /* This is not used.  */
225 #define FUNCTION_NAME           __gconv_transform_ucs4_internal
226
227
228 static inline int
229 __attribute ((always_inline))
230 ucs4_internal_loop (struct __gconv_step *step,
231                     struct __gconv_step_data *step_data,
232                     const unsigned char **inptrp, const unsigned char *inend,
233                     unsigned char **outptrp, unsigned char *outend,
234                     size_t *irreversible)
235 {
236   int flags = step_data->__flags;
237   const unsigned char *inptr = *inptrp;
238   unsigned char *outptr = *outptrp;
239   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
240   int result;
241   size_t cnt;
242
243   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
244     {
245       uint32_t inval;
246
247 #if __BYTE_ORDER == __LITTLE_ENDIAN
248       inval = bswap_32 (*(const uint32_t *) inptr);
249 #else
250       inval = *(const uint32_t *) inptr;
251 #endif
252
253       if (__builtin_expect (inval > 0x7fffffff, 0))
254         {
255           /* The value is too large.  We don't try transliteration here since
256              this is not an error because of the lack of possibilities to
257              represent the result.  This is a genuine bug in the input since
258              UCS4 does not allow such values.  */
259           if (irreversible == NULL)
260             /* We are transliterating, don't try to correct anything.  */
261             return __GCONV_ILLEGAL_INPUT;
262
263           if (flags & __GCONV_IGNORE_ERRORS)
264             {
265               /* Just ignore this character.  */
266               ++*irreversible;
267               continue;
268             }
269
270           *inptrp = inptr;
271           *outptrp = outptr;
272           return __GCONV_ILLEGAL_INPUT;
273         }
274
275       *((uint32_t *) outptr) = inval;
276       outptr += sizeof (uint32_t);
277     }
278
279   *inptrp = inptr;
280   *outptrp = outptr;
281
282   /* Determine the status.  */
283   if (*inptrp == inend)
284     result = __GCONV_EMPTY_INPUT;
285   else if (*outptrp + 4 > outend)
286     result = __GCONV_FULL_OUTPUT;
287   else
288     result = __GCONV_INCOMPLETE_INPUT;
289
290   return result;
291 }
292
293 #ifndef _STRING_ARCH_unaligned
294 static inline int
295 __attribute ((always_inline))
296 ucs4_internal_loop_unaligned (struct __gconv_step *step,
297                               struct __gconv_step_data *step_data,
298                               const unsigned char **inptrp,
299                               const unsigned char *inend,
300                               unsigned char **outptrp, unsigned char *outend,
301                               size_t *irreversible)
302 {
303   int flags = step_data->__flags;
304   const unsigned char *inptr = *inptrp;
305   unsigned char *outptr = *outptrp;
306   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
307   int result;
308   size_t cnt;
309
310   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
311     {
312       if (__builtin_expect (inptr[0] > 0x80, 0))
313         {
314           /* The value is too large.  We don't try transliteration here since
315              this is not an error because of the lack of possibilities to
316              represent the result.  This is a genuine bug in the input since
317              UCS4 does not allow such values.  */
318           if (irreversible == NULL)
319             /* We are transliterating, don't try to correct anything.  */
320             return __GCONV_ILLEGAL_INPUT;
321
322           if (flags & __GCONV_IGNORE_ERRORS)
323             {
324               /* Just ignore this character.  */
325               ++*irreversible;
326               continue;
327             }
328
329           *inptrp = inptr;
330           *outptrp = outptr;
331           return __GCONV_ILLEGAL_INPUT;
332         }
333
334 # if __BYTE_ORDER == __LITTLE_ENDIAN
335       outptr[3] = inptr[0];
336       outptr[2] = inptr[1];
337       outptr[1] = inptr[2];
338       outptr[0] = inptr[3];
339 # else
340       outptr[0] = inptr[0];
341       outptr[1] = inptr[1];
342       outptr[2] = inptr[2];
343       outptr[3] = inptr[3];
344 # endif
345       outptr += 4;
346     }
347
348   *inptrp = inptr;
349   *outptrp = outptr;
350
351   /* Determine the status.  */
352   if (*inptrp == inend)
353     result = __GCONV_EMPTY_INPUT;
354   else if (*outptrp + 4 > outend)
355     result = __GCONV_FULL_OUTPUT;
356   else
357     result = __GCONV_INCOMPLETE_INPUT;
358
359   return result;
360 }
361 #endif
362
363
364 static inline int
365 __attribute ((always_inline))
366 ucs4_internal_loop_single (struct __gconv_step *step,
367                            struct __gconv_step_data *step_data,
368                            const unsigned char **inptrp,
369                            const unsigned char *inend,
370                            unsigned char **outptrp, unsigned char *outend,
371                            size_t *irreversible)
372 {
373   mbstate_t *state = step_data->__statep;
374   int flags = step_data->__flags;
375   size_t cnt = state->__count & 7;
376
377   while (*inptrp < inend && cnt < 4)
378     state->__value.__wchb[cnt++] = *(*inptrp)++;
379
380   if (__builtin_expect (cnt < 4, 0))
381     {
382       /* Still not enough bytes.  Store the ones in the input buffer.  */
383       state->__count &= ~7;
384       state->__count |= cnt;
385
386       return __GCONV_INCOMPLETE_INPUT;
387     }
388
389   if (__builtin_expect (((unsigned char *) state->__value.__wchb)[0] > 0x80,
390                         0))
391     {
392       /* The value is too large.  We don't try transliteration here since
393          this is not an error because of the lack of possibilities to
394          represent the result.  This is a genuine bug in the input since
395          UCS4 does not allow such values.  */
396       if (!(flags & __GCONV_IGNORE_ERRORS))
397         {
398           *inptrp -= cnt - (state->__count & 7);
399           return __GCONV_ILLEGAL_INPUT;
400         }
401     }
402   else
403     {
404 #if __BYTE_ORDER == __LITTLE_ENDIAN
405       (*outptrp)[0] = state->__value.__wchb[3];
406       (*outptrp)[1] = state->__value.__wchb[2];
407       (*outptrp)[2] = state->__value.__wchb[1];
408       (*outptrp)[3] = state->__value.__wchb[0];
409 #elif __BYTE_ORDER == __BIG_ENDIAN
410       (*outptrp)[0] = state->__value.__wchb[0];
411       (*outptrp)[1] = state->__value.__wchb[1];
412       (*outptrp)[2] = state->__value.__wchb[2];
413       (*outptrp)[3] = state->__value.__wchb[3];
414 #endif
415
416       *outptrp += 4;
417     }
418
419   /* Clear the state buffer.  */
420   state->__count &= ~7;
421
422   return __GCONV_OK;
423 }
424
425 #include <iconv/skeleton.c>
426
427
428 /* Similarly for the little endian form.  */
429 #define DEFINE_INIT             0
430 #define DEFINE_FINI             0
431 #define MIN_NEEDED_FROM         4
432 #define MIN_NEEDED_TO           4
433 #define FROM_DIRECTION          1
434 #define FROM_LOOP               internal_ucs4le_loop
435 #define TO_LOOP                 internal_ucs4le_loop /* This is not used.  */
436 #define FUNCTION_NAME           __gconv_transform_internal_ucs4le
437
438
439 static inline int
440 __attribute ((always_inline))
441 internal_ucs4le_loop (struct __gconv_step *step,
442                       struct __gconv_step_data *step_data,
443                       const unsigned char **inptrp, const unsigned char *inend,
444                       unsigned char **outptrp, unsigned char *outend,
445                       size_t *irreversible)
446 {
447   const unsigned char *inptr = *inptrp;
448   unsigned char *outptr = *outptrp;
449   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
450   int result;
451
452 #if __BYTE_ORDER == __BIG_ENDIAN
453   /* Sigh, we have to do some real work.  */
454   size_t cnt;
455   uint32_t *outptr32 = (uint32_t *) outptr;
456
457   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
458     *outptr32++ = bswap_32 (*(const uint32_t *) inptr);
459   outptr = (unsigned char *) outptr32;
460
461   *inptrp = inptr;
462   *outptrp = outptr;
463 #elif __BYTE_ORDER == __LITTLE_ENDIAN
464   /* Simply copy the data.  */
465   *inptrp = inptr + n_convert * 4;
466   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
467 #else
468 # error "This endianess is not supported."
469 #endif
470
471   /* Determine the status.  */
472   if (*inptrp == inend)
473     result = __GCONV_EMPTY_INPUT;
474   else if (*outptrp + 4 > outend)
475     result = __GCONV_FULL_OUTPUT;
476   else
477     result = __GCONV_INCOMPLETE_INPUT;
478
479   return result;
480 }
481
482 #ifndef _STRING_ARCH_unaligned
483 static inline int
484 __attribute ((always_inline))
485 internal_ucs4le_loop_unaligned (struct __gconv_step *step,
486                                 struct __gconv_step_data *step_data,
487                                 const unsigned char **inptrp,
488                                 const unsigned char *inend,
489                                 unsigned char **outptrp, unsigned char *outend,
490                                 size_t *irreversible)
491 {
492   const unsigned char *inptr = *inptrp;
493   unsigned char *outptr = *outptrp;
494   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
495   int result;
496
497 # if __BYTE_ORDER == __BIG_ENDIAN
498   /* Sigh, we have to do some real work.  */
499   size_t cnt;
500
501   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4, outptr += 4)
502     {
503       outptr[0] = inptr[3];
504       outptr[1] = inptr[2];
505       outptr[2] = inptr[1];
506       outptr[3] = inptr[0];
507     }
508
509   *inptrp = inptr;
510   *outptrp = outptr;
511 # elif __BYTE_ORDER == __LITTLE_ENDIAN
512   /* Simply copy the data.  */
513   *inptrp = inptr + n_convert * 4;
514   *outptrp = __mempcpy (outptr, inptr, n_convert * 4);
515 # else
516 #  error "This endianess is not supported."
517 # endif
518
519   /* Determine the status.  */
520   if (*inptrp == inend)
521     result = __GCONV_EMPTY_INPUT;
522   else if (*inptrp + 4 > inend)
523     result = __GCONV_INCOMPLETE_INPUT;
524   else
525     {
526       assert (*outptrp + 4 > outend);
527       result = __GCONV_FULL_OUTPUT;
528     }
529
530   return result;
531 }
532 #endif
533
534
535 static inline int
536 __attribute ((always_inline))
537 internal_ucs4le_loop_single (struct __gconv_step *step,
538                              struct __gconv_step_data *step_data,
539                              const unsigned char **inptrp,
540                              const unsigned char *inend,
541                              unsigned char **outptrp, unsigned char *outend,
542                              size_t *irreversible)
543 {
544   mbstate_t *state = step_data->__statep;
545   size_t cnt = state->__count & 7;
546
547   while (*inptrp < inend && cnt < 4)
548     state->__value.__wchb[cnt++] = *(*inptrp)++;
549
550   if (__builtin_expect (cnt < 4, 0))
551     {
552       /* Still not enough bytes.  Store the ones in the input buffer.  */
553       state->__count &= ~7;
554       state->__count |= cnt;
555
556       return __GCONV_INCOMPLETE_INPUT;
557     }
558
559 #if __BYTE_ORDER == __BIG_ENDIAN
560   (*outptrp)[0] = state->__value.__wchb[3];
561   (*outptrp)[1] = state->__value.__wchb[2];
562   (*outptrp)[2] = state->__value.__wchb[1];
563   (*outptrp)[3] = state->__value.__wchb[0];
564
565 #else
566   /* XXX unaligned */
567   (*outptrp)[0] = state->__value.__wchb[0];
568   (*outptrp)[1] = state->__value.__wchb[1];
569   (*outptrp)[2] = state->__value.__wchb[2];
570   (*outptrp)[3] = state->__value.__wchb[3];
571
572 #endif
573
574   *outptrp += 4;
575
576   /* Clear the state buffer.  */
577   state->__count &= ~7;
578
579   return __GCONV_OK;
580 }
581
582 #include <iconv/skeleton.c>
583
584
585 /* And finally from UCS4-LE to the internal encoding.  */
586 #define DEFINE_INIT             0
587 #define DEFINE_FINI             0
588 #define MIN_NEEDED_FROM         4
589 #define MIN_NEEDED_TO           4
590 #define FROM_DIRECTION          1
591 #define FROM_LOOP               ucs4le_internal_loop
592 #define TO_LOOP                 ucs4le_internal_loop /* This is not used.  */
593 #define FUNCTION_NAME           __gconv_transform_ucs4le_internal
594
595
596 static inline int
597 __attribute ((always_inline))
598 ucs4le_internal_loop (struct __gconv_step *step,
599                       struct __gconv_step_data *step_data,
600                       const unsigned char **inptrp, const unsigned char *inend,
601                       unsigned char **outptrp, unsigned char *outend,
602                       size_t *irreversible)
603 {
604   int flags = step_data->__flags;
605   const unsigned char *inptr = *inptrp;
606   unsigned char *outptr = *outptrp;
607   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
608   int result;
609   size_t cnt;
610
611   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
612     {
613       uint32_t inval;
614
615 #if __BYTE_ORDER == __BIG_ENDIAN
616       inval = bswap_32 (*(const uint32_t *) inptr);
617 #else
618       inval = *(const uint32_t *) inptr;
619 #endif
620
621       if (__builtin_expect (inval > 0x7fffffff, 0))
622         {
623           /* The value is too large.  We don't try transliteration here since
624              this is not an error because of the lack of possibilities to
625              represent the result.  This is a genuine bug in the input since
626              UCS4 does not allow such values.  */
627           if (irreversible == NULL)
628             /* We are transliterating, don't try to correct anything.  */
629             return __GCONV_ILLEGAL_INPUT;
630
631           if (flags & __GCONV_IGNORE_ERRORS)
632             {
633               /* Just ignore this character.  */
634               ++*irreversible;
635               continue;
636             }
637
638           return __GCONV_ILLEGAL_INPUT;
639         }
640
641       *((uint32_t *) outptr) = inval;
642       outptr += sizeof (uint32_t);
643     }
644
645   *inptrp = inptr;
646   *outptrp = outptr;
647
648   /* Determine the status.  */
649   if (*inptrp == inend)
650     result = __GCONV_EMPTY_INPUT;
651   else if (*inptrp + 4 > inend)
652     result = __GCONV_INCOMPLETE_INPUT;
653   else
654     {
655       assert (*outptrp + 4 > outend);
656       result = __GCONV_FULL_OUTPUT;
657     }
658
659   return result;
660 }
661
662 #ifndef _STRING_ARCH_unaligned
663 static inline int
664 __attribute ((always_inline))
665 ucs4le_internal_loop_unaligned (struct __gconv_step *step,
666                                 struct __gconv_step_data *step_data,
667                                 const unsigned char **inptrp,
668                                 const unsigned char *inend,
669                                 unsigned char **outptrp, unsigned char *outend,
670                                 size_t *irreversible)
671 {
672   int flags = step_data->__flags;
673   const unsigned char *inptr = *inptrp;
674   unsigned char *outptr = *outptrp;
675   size_t n_convert = MIN (inend - inptr, outend - outptr) / 4;
676   int result;
677   size_t cnt;
678
679   for (cnt = 0; cnt < n_convert; ++cnt, inptr += 4)
680     {
681       if (__builtin_expect (inptr[3] > 0x80, 0))
682         {
683           /* The value is too large.  We don't try transliteration here since
684              this is not an error because of the lack of possibilities to
685              represent the result.  This is a genuine bug in the input since
686              UCS4 does not allow such values.  */
687           if (irreversible == NULL)
688             /* We are transliterating, don't try to correct anything.  */
689             return __GCONV_ILLEGAL_INPUT;
690
691           if (flags & __GCONV_IGNORE_ERRORS)
692             {
693               /* Just ignore this character.  */
694               ++*irreversible;
695               continue;
696             }
697
698           *inptrp = inptr;
699           *outptrp = outptr;
700           return __GCONV_ILLEGAL_INPUT;
701         }
702
703 # if __BYTE_ORDER == __BIG_ENDIAN
704       outptr[3] = inptr[0];
705       outptr[2] = inptr[1];
706       outptr[1] = inptr[2];
707       outptr[0] = inptr[3];
708 # else
709       outptr[0] = inptr[0];
710       outptr[1] = inptr[1];
711       outptr[2] = inptr[2];
712       outptr[3] = inptr[3];
713 # endif
714
715       outptr += 4;
716     }
717
718   *inptrp = inptr;
719   *outptrp = outptr;
720
721   /* Determine the status.  */
722   if (*inptrp == inend)
723     result = __GCONV_EMPTY_INPUT;
724   else if (*inptrp + 4 > inend)
725     result = __GCONV_INCOMPLETE_INPUT;
726   else
727     {
728       assert (*outptrp + 4 > outend);
729       result = __GCONV_FULL_OUTPUT;
730     }
731
732   return result;
733 }
734 #endif
735
736
737 static inline int
738 __attribute ((always_inline))
739 ucs4le_internal_loop_single (struct __gconv_step *step,
740                              struct __gconv_step_data *step_data,
741                              const unsigned char **inptrp,
742                              const unsigned char *inend,
743                              unsigned char **outptrp, unsigned char *outend,
744                              size_t *irreversible)
745 {
746   mbstate_t *state = step_data->__statep;
747   int flags = step_data->__flags;
748   size_t cnt = state->__count & 7;
749
750   while (*inptrp < inend && cnt < 4)
751     state->__value.__wchb[cnt++] = *(*inptrp)++;
752
753   if (__builtin_expect (cnt < 4, 0))
754     {
755       /* Still not enough bytes.  Store the ones in the input buffer.  */
756       state->__count &= ~7;
757       state->__count |= cnt;
758
759       return __GCONV_INCOMPLETE_INPUT;
760     }
761
762   if (__builtin_expect (((unsigned char *) state->__value.__wchb)[3] > 0x80,
763                         0))
764     {
765       /* The value is too large.  We don't try transliteration here since
766          this is not an error because of the lack of possibilities to
767          represent the result.  This is a genuine bug in the input since
768          UCS4 does not allow such values.  */
769       if (!(flags & __GCONV_IGNORE_ERRORS))
770         return __GCONV_ILLEGAL_INPUT;
771     }
772   else
773     {
774 #if __BYTE_ORDER == __BIG_ENDIAN
775       (*outptrp)[0] = state->__value.__wchb[3];
776       (*outptrp)[1] = state->__value.__wchb[2];
777       (*outptrp)[2] = state->__value.__wchb[1];
778       (*outptrp)[3] = state->__value.__wchb[0];
779 #else
780       (*outptrp)[0] = state->__value.__wchb[0];
781       (*outptrp)[1] = state->__value.__wchb[1];
782       (*outptrp)[2] = state->__value.__wchb[2];
783       (*outptrp)[3] = state->__value.__wchb[3];
784 #endif
785
786       *outptrp += 4;
787     }
788
789   /* Clear the state buffer.  */
790   state->__count &= ~7;
791
792   return __GCONV_OK;
793 }
794
795 #include <iconv/skeleton.c>
796
797
798 /* Convert from ISO 646-IRV to the internal (UCS4-like) format.  */
799 #define DEFINE_INIT             0
800 #define DEFINE_FINI             0
801 #define MIN_NEEDED_FROM         1
802 #define MIN_NEEDED_TO           4
803 #define FROM_DIRECTION          1
804 #define FROM_LOOP               ascii_internal_loop
805 #define TO_LOOP                 ascii_internal_loop /* This is not used.  */
806 #define FUNCTION_NAME           __gconv_transform_ascii_internal
807 #define ONE_DIRECTION           1
808
809 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
810 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
811 #define LOOPFCT                 FROM_LOOP
812 #define BODY \
813   {                                                                           \
814     if (__builtin_expect (*inptr > '\x7f', 0))                                \
815       {                                                                       \
816         /* The value is too large.  We don't try transliteration here since   \
817            this is not an error because of the lack of possibilities to       \
818            represent the result.  This is a genuine bug in the input since    \
819            ASCII does not allow such values.  */                              \
820         STANDARD_FROM_LOOP_ERR_HANDLER (1);                                   \
821       }                                                                       \
822     else                                                                      \
823       {                                                                       \
824         /* It's an one byte sequence.  */                                     \
825         *((uint32_t *) outptr) = *inptr++;                                    \
826         outptr += sizeof (uint32_t);                                          \
827       }                                                                       \
828   }
829 #define LOOP_NEED_FLAGS
830 #include <iconv/loop.c>
831 #include <iconv/skeleton.c>
832
833
834 /* Convert from the internal (UCS4-like) format to ISO 646-IRV.  */
835 #define DEFINE_INIT             0
836 #define DEFINE_FINI             0
837 #define MIN_NEEDED_FROM         4
838 #define MIN_NEEDED_TO           1
839 #define FROM_DIRECTION          1
840 #define FROM_LOOP               internal_ascii_loop
841 #define TO_LOOP                 internal_ascii_loop /* This is not used.  */
842 #define FUNCTION_NAME           __gconv_transform_internal_ascii
843 #define ONE_DIRECTION           1
844
845 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
846 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
847 #define LOOPFCT                 FROM_LOOP
848 #define BODY \
849   {                                                                           \
850     if (__builtin_expect (*((const uint32_t *) inptr) > 0x7f, 0))             \
851       {                                                                       \
852         UNICODE_TAG_HANDLER (*((const uint32_t *) inptr), 4);                 \
853         STANDARD_TO_LOOP_ERR_HANDLER (4);                                     \
854       }                                                                       \
855     else                                                                      \
856       {                                                                       \
857         /* It's an one byte sequence.  */                                     \
858         *outptr++ = *((const uint32_t *) inptr);                              \
859         inptr += sizeof (uint32_t);                                           \
860       }                                                                       \
861   }
862 #define LOOP_NEED_FLAGS
863 #include <iconv/loop.c>
864 #include <iconv/skeleton.c>
865
866
867 /* Convert from the internal (UCS4-like) format to UTF-8.  */
868 #define DEFINE_INIT             0
869 #define DEFINE_FINI             0
870 #define MIN_NEEDED_FROM         4
871 #define MIN_NEEDED_TO           1
872 #define MAX_NEEDED_TO           6
873 #define FROM_DIRECTION          1
874 #define FROM_LOOP               internal_utf8_loop
875 #define TO_LOOP                 internal_utf8_loop /* This is not used.  */
876 #define FUNCTION_NAME           __gconv_transform_internal_utf8
877 #define ONE_DIRECTION           1
878
879 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
880 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
881 #define MAX_NEEDED_OUTPUT       MAX_NEEDED_TO
882 #define LOOPFCT                 FROM_LOOP
883 #define BODY \
884   {                                                                           \
885     uint32_t wc = *((const uint32_t *) inptr);                                \
886                                                                               \
887     if (__builtin_expect (wc < 0x80, 1))                                      \
888       /* It's an one byte sequence.  */                                       \
889       *outptr++ = (unsigned char) wc;                                         \
890     else if (__builtin_expect (wc <= 0x7fffffff, 1))                          \
891       {                                                                       \
892         size_t step;                                                          \
893         unsigned char *start;                                                 \
894                                                                               \
895         for (step = 2; step < 6; ++step)                                      \
896           if ((wc & (~(uint32_t)0 << (5 * step + 1))) == 0)                   \
897             break;                                                            \
898                                                                               \
899         if (__builtin_expect (outptr + step > outend, 0))                     \
900           {                                                                   \
901             /* Too long.  */                                                  \
902             result = __GCONV_FULL_OUTPUT;                                     \
903             break;                                                            \
904           }                                                                   \
905                                                                               \
906         start = outptr;                                                       \
907         *outptr = (unsigned char) (~0xff >> step);                            \
908         outptr += step;                                                       \
909         do                                                                    \
910           {                                                                   \
911             start[--step] = 0x80 | (wc & 0x3f);                               \
912             wc >>= 6;                                                         \
913           }                                                                   \
914         while (step > 1);                                                     \
915         start[0] |= wc;                                                       \
916       }                                                                       \
917     else                                                                      \
918       {                                                                       \
919         STANDARD_TO_LOOP_ERR_HANDLER (4);                                     \
920       }                                                                       \
921                                                                               \
922     inptr += 4;                                                               \
923   }
924 #define LOOP_NEED_FLAGS
925 #include <iconv/loop.c>
926 #include <iconv/skeleton.c>
927
928
929 /* Convert from UTF-8 to the internal (UCS4-like) format.  */
930 #define DEFINE_INIT             0
931 #define DEFINE_FINI             0
932 #define MIN_NEEDED_FROM         1
933 #define MAX_NEEDED_FROM         6
934 #define MIN_NEEDED_TO           4
935 #define FROM_DIRECTION          1
936 #define FROM_LOOP               utf8_internal_loop
937 #define TO_LOOP                 utf8_internal_loop /* This is not used.  */
938 #define FUNCTION_NAME           __gconv_transform_utf8_internal
939 #define ONE_DIRECTION           1
940
941 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
942 #define MAX_NEEDED_INPUT        MAX_NEEDED_FROM
943 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
944 #define LOOPFCT                 FROM_LOOP
945 #define BODY \
946   {                                                                           \
947     /* Next input byte.  */                                                   \
948     uint32_t ch = *inptr;                                                     \
949                                                                               \
950     if (__builtin_expect (ch < 0x80, 1))                                      \
951       {                                                                       \
952         /* One byte sequence.  */                                             \
953         ++inptr;                                                              \
954       }                                                                       \
955     else                                                                      \
956       {                                                                       \
957         uint_fast32_t cnt;                                                    \
958         uint_fast32_t i;                                                      \
959                                                                               \
960         if (ch >= 0xc2 && ch < 0xe0)                                          \
961           {                                                                   \
962             /* We expect two bytes.  The first byte cannot be 0xc0 or 0xc1,   \
963                otherwise the wide character could have been represented       \
964                using a single byte.  */                                       \
965             cnt = 2;                                                          \
966             ch &= 0x1f;                                                       \
967           }                                                                   \
968         else if (__builtin_expect ((ch & 0xf0) == 0xe0, 1))                   \
969           {                                                                   \
970             /* We expect three bytes.  */                                     \
971             cnt = 3;                                                          \
972             ch &= 0x0f;                                                       \
973           }                                                                   \
974         else if (__builtin_expect ((ch & 0xf8) == 0xf0, 1))                   \
975           {                                                                   \
976             /* We expect four bytes.  */                                      \
977             cnt = 4;                                                          \
978             ch &= 0x07;                                                       \
979           }                                                                   \
980         else if (__builtin_expect ((ch & 0xfc) == 0xf8, 1))                   \
981           {                                                                   \
982             /* We expect five bytes.  */                                      \
983             cnt = 5;                                                          \
984             ch &= 0x03;                                                       \
985           }                                                                   \
986         else if (__builtin_expect ((ch & 0xfe) == 0xfc, 1))                   \
987           {                                                                   \
988             /* We expect six bytes.  */                                       \
989             cnt = 6;                                                          \
990             ch &= 0x01;                                                       \
991           }                                                                   \
992         else                                                                  \
993           {                                                                   \
994             /* Search the end of this ill-formed UTF-8 character.  This       \
995                is the next byte with (x & 0xc0) != 0x80.  */                  \
996             i = 0;                                                            \
997             do                                                                \
998               ++i;                                                            \
999             while (inptr + i < inend                                          \
1000                    && (*(inptr + i) & 0xc0) == 0x80                           \
1001                    && i < 5);                                                 \
1002                                                                               \
1003           errout:                                                             \
1004             STANDARD_FROM_LOOP_ERR_HANDLER (i);                               \
1005           }                                                                   \
1006                                                                               \
1007         if (__builtin_expect (inptr + cnt > inend, 0))                        \
1008           {                                                                   \
1009             /* We don't have enough input.  But before we report that check   \
1010                that all the bytes are correct.  */                            \
1011             for (i = 1; inptr + i < inend; ++i)                               \
1012               if ((inptr[i] & 0xc0) != 0x80)                                  \
1013                 break;                                                        \
1014                                                                               \
1015             if (__builtin_expect (inptr + i == inend, 1))                     \
1016               {                                                               \
1017                 result = __GCONV_INCOMPLETE_INPUT;                            \
1018                 break;                                                        \
1019               }                                                               \
1020                                                                               \
1021             goto errout;                                                      \
1022           }                                                                   \
1023                                                                               \
1024         /* Read the possible remaining bytes.  */                             \
1025         for (i = 1; i < cnt; ++i)                                             \
1026           {                                                                   \
1027             uint32_t byte = inptr[i];                                         \
1028                                                                               \
1029             if ((byte & 0xc0) != 0x80)                                        \
1030               /* This is an illegal encoding.  */                             \
1031               break;                                                          \
1032                                                                               \
1033             ch <<= 6;                                                         \
1034             ch |= byte & 0x3f;                                                \
1035           }                                                                   \
1036                                                                               \
1037         /* If i < cnt, some trail byte was not >= 0x80, < 0xc0.               \
1038            If cnt > 2 and ch < 2^(5*cnt-4), the wide character ch could       \
1039            have been represented with fewer than cnt bytes.  */               \
1040         if (i < cnt || (cnt > 2 && (ch >> (5 * cnt - 4)) == 0)                \
1041             /* Do not accept UTF-16 surrogates.  */                           \
1042             || (ch >= 0xd800 && ch <= 0xdfff))                                \
1043           {                                                                   \
1044             /* This is an illegal encoding.  */                               \
1045             goto errout;                                                      \
1046           }                                                                   \
1047                                                                               \
1048         inptr += cnt;                                                         \
1049       }                                                                       \
1050                                                                               \
1051     /* Now adjust the pointers and store the result.  */                      \
1052     *((uint32_t *) outptr) = ch;                                              \
1053     outptr += sizeof (uint32_t);                                              \
1054   }
1055 #define LOOP_NEED_FLAGS
1056
1057 #define STORE_REST \
1058   {                                                                           \
1059     /* We store the remaining bytes while converting them into the UCS4       \
1060        format.  We can assume that the first byte in the buffer is            \
1061        correct and that it requires a larger number of bytes than there       \
1062        are in the input buffer.  */                                           \
1063     wint_t ch = **inptrp;                                                     \
1064     size_t cnt, r;                                                            \
1065                                                                               \
1066     state->__count = inend - *inptrp;                                         \
1067                                                                               \
1068     if (ch >= 0xc2 && ch < 0xe0)                                              \
1069       {                                                                       \
1070         /* We expect two bytes.  The first byte cannot be 0xc0 or             \
1071            0xc1, otherwise the wide character could have been                 \
1072            represented using a single byte.  */                               \
1073         cnt = 2;                                                              \
1074         ch &= 0x1f;                                                           \
1075       }                                                                       \
1076     else if (__builtin_expect ((ch & 0xf0) == 0xe0, 1))                       \
1077       {                                                                       \
1078         /* We expect three bytes.  */                                         \
1079         cnt = 3;                                                              \
1080         ch &= 0x0f;                                                           \
1081       }                                                                       \
1082     else if (__builtin_expect ((ch & 0xf8) == 0xf0, 1))                       \
1083       {                                                                       \
1084         /* We expect four bytes.  */                                          \
1085         cnt = 4;                                                              \
1086         ch &= 0x07;                                                           \
1087       }                                                                       \
1088     else if (__builtin_expect ((ch & 0xfc) == 0xf8, 1))                       \
1089       {                                                                       \
1090         /* We expect five bytes.  */                                          \
1091         cnt = 5;                                                              \
1092         ch &= 0x03;                                                           \
1093       }                                                                       \
1094     else                                                                      \
1095       {                                                                       \
1096         /* We expect six bytes.  */                                           \
1097         cnt = 6;                                                              \
1098         ch &= 0x01;                                                           \
1099       }                                                                       \
1100                                                                               \
1101     /* The first byte is already consumed.  */                                \
1102     r = cnt - 1;                                                              \
1103     while (++(*inptrp) < inend)                                               \
1104       {                                                                       \
1105         ch <<= 6;                                                             \
1106         ch |= **inptrp & 0x3f;                                                \
1107         --r;                                                                  \
1108       }                                                                       \
1109                                                                               \
1110     /* Shift for the so far missing bytes.  */                                \
1111     ch <<= r * 6;                                                             \
1112                                                                               \
1113     /* Store the number of bytes expected for the entire sequence.  */        \
1114     state->__count |= cnt << 8;                                               \
1115                                                                               \
1116     /* Store the value.  */                                                   \
1117     state->__value.__wch = ch;                                                \
1118   }
1119
1120 #define UNPACK_BYTES \
1121   {                                                                           \
1122     static const unsigned char inmask[5] = { 0xc0, 0xe0, 0xf0, 0xf8, 0xfc };  \
1123     wint_t wch = state->__value.__wch;                                        \
1124     size_t ntotal = state->__count >> 8;                                      \
1125                                                                               \
1126     inlen = state->__count & 255;                                             \
1127                                                                               \
1128     bytebuf[0] = inmask[ntotal - 2];                                          \
1129                                                                               \
1130     do                                                                        \
1131       {                                                                       \
1132         if (--ntotal < inlen)                                                 \
1133           bytebuf[ntotal] = 0x80 | (wch & 0x3f);                              \
1134         wch >>= 6;                                                            \
1135       }                                                                       \
1136     while (ntotal > 1);                                                       \
1137                                                                               \
1138     bytebuf[0] |= wch;                                                        \
1139   }
1140
1141 #define CLEAR_STATE \
1142   state->__count = 0
1143
1144
1145 #include <iconv/loop.c>
1146 #include <iconv/skeleton.c>
1147
1148
1149 /* Convert from UCS2 to the internal (UCS4-like) format.  */
1150 #define DEFINE_INIT             0
1151 #define DEFINE_FINI             0
1152 #define MIN_NEEDED_FROM         2
1153 #define MIN_NEEDED_TO           4
1154 #define FROM_DIRECTION          1
1155 #define FROM_LOOP               ucs2_internal_loop
1156 #define TO_LOOP                 ucs2_internal_loop /* This is not used.  */
1157 #define FUNCTION_NAME           __gconv_transform_ucs2_internal
1158 #define ONE_DIRECTION           1
1159
1160 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
1161 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
1162 #define LOOPFCT                 FROM_LOOP
1163 #define BODY \
1164   {                                                                           \
1165     uint16_t u1 = get16 (inptr);                                              \
1166                                                                               \
1167     if (__builtin_expect (u1 >= 0xd800 && u1 < 0xe000, 0))                    \
1168       {                                                                       \
1169         /* Surrogate characters in UCS-2 input are not valid.  Reject         \
1170            them.  (Catching this here is not security relevant.)  */          \
1171         STANDARD_FROM_LOOP_ERR_HANDLER (2);                                   \
1172       }                                                                       \
1173                                                                               \
1174     *((uint32_t *) outptr) = u1;                                              \
1175     outptr += sizeof (uint32_t);                                              \
1176     inptr += 2;                                                               \
1177   }
1178 #define LOOP_NEED_FLAGS
1179 #include <iconv/loop.c>
1180 #include <iconv/skeleton.c>
1181
1182
1183 /* Convert from the internal (UCS4-like) format to UCS2.  */
1184 #define DEFINE_INIT             0
1185 #define DEFINE_FINI             0
1186 #define MIN_NEEDED_FROM         4
1187 #define MIN_NEEDED_TO           2
1188 #define FROM_DIRECTION          1
1189 #define FROM_LOOP               internal_ucs2_loop
1190 #define TO_LOOP                 internal_ucs2_loop /* This is not used.  */
1191 #define FUNCTION_NAME           __gconv_transform_internal_ucs2
1192 #define ONE_DIRECTION           1
1193
1194 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
1195 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
1196 #define LOOPFCT                 FROM_LOOP
1197 #define BODY \
1198   {                                                                           \
1199     uint32_t val = *((const uint32_t *) inptr);                               \
1200                                                                               \
1201     if (__builtin_expect (val >= 0x10000, 0))                                 \
1202       {                                                                       \
1203         UNICODE_TAG_HANDLER (val, 4);                                         \
1204         STANDARD_TO_LOOP_ERR_HANDLER (4);                                     \
1205       }                                                                       \
1206     else if (__builtin_expect (val >= 0xd800 && val < 0xe000, 0))             \
1207       {                                                                       \
1208         /* Surrogate characters in UCS-4 input are not valid.                 \
1209            We must catch this, because the UCS-2 output might be              \
1210            interpreted as UTF-16 by other programs.  If we let                \
1211            surrogates pass through, attackers could make a security           \
1212            hole exploit by synthesizing any desired plane 1-16                \
1213            character.  */                                                     \
1214         result = __GCONV_ILLEGAL_INPUT;                                       \
1215         if (! ignore_errors_p ())                                             \
1216           break;                                                              \
1217         inptr += 4;                                                           \
1218         ++*irreversible;                                                      \
1219         continue;                                                             \
1220       }                                                                       \
1221     else                                                                      \
1222       {                                                                       \
1223         put16 (outptr, val);                                                  \
1224         outptr += sizeof (uint16_t);                                          \
1225         inptr += 4;                                                           \
1226       }                                                                       \
1227   }
1228 #define LOOP_NEED_FLAGS
1229 #include <iconv/loop.c>
1230 #include <iconv/skeleton.c>
1231
1232
1233 /* Convert from UCS2 in other endianness to the internal (UCS4-like) format. */
1234 #define DEFINE_INIT             0
1235 #define DEFINE_FINI             0
1236 #define MIN_NEEDED_FROM         2
1237 #define MIN_NEEDED_TO           4
1238 #define FROM_DIRECTION          1
1239 #define FROM_LOOP               ucs2reverse_internal_loop
1240 #define TO_LOOP                 ucs2reverse_internal_loop/* This is not used.*/
1241 #define FUNCTION_NAME           __gconv_transform_ucs2reverse_internal
1242 #define ONE_DIRECTION           1
1243
1244 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
1245 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
1246 #define LOOPFCT                 FROM_LOOP
1247 #define BODY \
1248   {                                                                           \
1249     uint16_t u1 = bswap_16 (get16 (inptr));                                   \
1250                                                                               \
1251     if (__builtin_expect (u1 >= 0xd800 && u1 < 0xe000, 0))                    \
1252       {                                                                       \
1253         /* Surrogate characters in UCS-2 input are not valid.  Reject         \
1254            them.  (Catching this here is not security relevant.)  */          \
1255         if (! ignore_errors_p ())                                             \
1256           {                                                                   \
1257             result = __GCONV_ILLEGAL_INPUT;                                   \
1258             break;                                                            \
1259           }                                                                   \
1260         inptr += 2;                                                           \
1261         ++*irreversible;                                                      \
1262         continue;                                                             \
1263       }                                                                       \
1264                                                                               \
1265     *((uint32_t *) outptr) = u1;                                              \
1266     outptr += sizeof (uint32_t);                                              \
1267     inptr += 2;                                                               \
1268   }
1269 #define LOOP_NEED_FLAGS
1270 #include <iconv/loop.c>
1271 #include <iconv/skeleton.c>
1272
1273
1274 /* Convert from the internal (UCS4-like) format to UCS2 in other endianness. */
1275 #define DEFINE_INIT             0
1276 #define DEFINE_FINI             0
1277 #define MIN_NEEDED_FROM         4
1278 #define MIN_NEEDED_TO           2
1279 #define FROM_DIRECTION          1
1280 #define FROM_LOOP               internal_ucs2reverse_loop
1281 #define TO_LOOP                 internal_ucs2reverse_loop/* This is not used.*/
1282 #define FUNCTION_NAME           __gconv_transform_internal_ucs2reverse
1283 #define ONE_DIRECTION           1
1284
1285 #define MIN_NEEDED_INPUT        MIN_NEEDED_FROM
1286 #define MIN_NEEDED_OUTPUT       MIN_NEEDED_TO
1287 #define LOOPFCT                 FROM_LOOP
1288 #define BODY \
1289   {                                                                           \
1290     uint32_t val = *((const uint32_t *) inptr);                               \
1291     if (__builtin_expect (val >= 0x10000, 0))                                 \
1292       {                                                                       \
1293         UNICODE_TAG_HANDLER (val, 4);                                         \
1294         STANDARD_TO_LOOP_ERR_HANDLER (4);                                     \
1295       }                                                                       \
1296     else if (__builtin_expect (val >= 0xd800 && val < 0xe000, 0))             \
1297       {                                                                       \
1298         /* Surrogate characters in UCS-4 input are not valid.                 \
1299            We must catch this, because the UCS-2 output might be              \
1300            interpreted as UTF-16 by other programs.  If we let                \
1301            surrogates pass through, attackers could make a security           \
1302            hole exploit by synthesizing any desired plane 1-16                \
1303            character.  */                                                     \
1304         if (! ignore_errors_p ())                                             \
1305           {                                                                   \
1306             result = __GCONV_ILLEGAL_INPUT;                                   \
1307             break;                                                            \
1308           }                                                                   \
1309         inptr += 4;                                                           \
1310         ++*irreversible;                                                      \
1311         continue;                                                             \
1312       }                                                                       \
1313     else                                                                      \
1314       {                                                                       \
1315         put16 (outptr, bswap_16 (val));                                       \
1316         outptr += sizeof (uint16_t);                                          \
1317         inptr += 4;                                                           \
1318       }                                                                       \
1319   }
1320 #define LOOP_NEED_FLAGS
1321 #include <iconv/loop.c>
1322 #include <iconv/skeleton.c>