Use separate test module for dns-cert.c.
[gnupg.git] / common / utf8conv.c
1 /* utf8conf.c -  UTF8 character set conversion
2  * Copyright (C) 1994, 1998, 1999, 2000, 2001, 2003, 2006,
3  *               2008, 2010  Free Software Foundation, Inc.
4  *
5  * This file is part of JNLIB, which is a subsystem of GnuPG.
6  *
7  * JNLIB is free software; you can redistribute it and/or modify it
8  * under the terms of either
9  *
10  *   - the GNU Lesser General Public License as published by the Free
11  *     Software Foundation; either version 3 of the License, or (at
12  *     your option) any later version.
13  *
14  * or
15  *
16  *   - the GNU General Public License as published by the Free
17  *     Software Foundation; either version 2 of the License, or (at
18  *     your option) any later version.
19  *
20  * or both in parallel, as here.
21  *
22  * JNLIB is distributed in the hope that it will be useful, but
23  * WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * General Public License for more details.
26  *
27  * You should have received a copies of the GNU General Public License
28  * and the GNU Lesser General Public License along with this program;
29  * if not, see <http://www.gnu.org/licenses/>.
30  */
31
32 #include <config.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdarg.h>
36 #include <ctype.h>
37 #ifdef HAVE_LANGINFO_CODESET
38 #include <langinfo.h>
39 #endif
40 #include <errno.h>
41 #ifndef HAVE_W32_SYSTEM
42 # include <iconv.h>
43 #endif
44
45 #include "libjnlib-config.h"
46 #include "stringhelp.h"
47 #include "dynload.h"
48 #include "utf8conv.h"
49
50 #ifndef MB_LEN_MAX
51 #define MB_LEN_MAX 16
52 #endif
53
54 static const char *active_charset_name = "iso-8859-1";
55 static int no_translation;     /* Set to true if we let simply pass through. */
56 static int use_iconv;          /* iconv comversion fucntions required. */
57
58
59 /* Under W32 we dlopen the iconv dll and don't require any iconv
60    related headers at all.  However we need to define some stuff.  */
61 #ifdef HAVE_W32_SYSTEM
62 typedef void *iconv_t;
63 #ifndef ICONV_CONST
64 #define ICONV_CONST
65 #endif
66 static iconv_t (* __stdcall iconv_open) (const char *tocode,
67                                          const char *fromcode);
68 static size_t  (* __stdcall iconv) (iconv_t cd,
69                                     char **inbuf, size_t *inbytesleft,
70                                     char **outbuf, size_t *outbytesleft);
71 static int     (* __stdcall iconv_close) (iconv_t cd);
72
73 static int
74 load_libiconv (void)
75 {
76 #ifdef HAVE_W32CE_SYSTEM
77   return -1; /* FIXME No libiconv yet - Need to investigate whether it
78                 is at all required.  */
79 #else
80   static int done;
81
82   if (!done)
83     {
84       void *handle;
85
86       done = 1; /* Do it right now because we might get called recursivly
87                    through gettext.  */
88
89       handle = dlopen ("iconv.dll", RTLD_LAZY);
90       if (handle)
91         {
92           iconv_open  = dlsym (handle, "libiconv_open");
93           if (iconv_open)
94             iconv = dlsym (handle, "libiconv");
95           if (iconv)
96             iconv_close = dlsym (handle, "libiconv_close");
97         }
98       if (!handle || !iconv_close)
99         {
100           log_info (_("error loading `%s': %s\n"),
101                      "iconv.dll",  dlerror ());
102           log_info (_("please see %s for more information\n"),
103                     "http://www.gnupg.org/download/iconv.html");
104           iconv_open = NULL;
105           iconv = NULL;
106           iconv_close = NULL;
107           if (handle)
108             dlclose (handle);
109         }
110     }
111   return iconv_open? 0: -1;
112 #endif
113 }
114 #endif /*HAVE_W32_SYSTEM*/
115
116
117 /* Error handler for iconv failures. This is needed to not clutter the
118    output with repeated diagnostics about a missing conversion. */
119 static void
120 handle_iconv_error (const char *to, const char *from, int use_fallback)
121 {
122   if (errno == EINVAL)
123     {
124       static int shown1, shown2;
125       int x;
126
127       if (to && !strcmp (to, "utf-8"))
128         {
129           x = shown1;
130           shown1 = 1;
131         }
132       else
133         {
134           x = shown2;
135           shown2 = 1;
136         }
137
138       if (!x)
139         log_info (_("conversion from `%s' to `%s' not available\n"),
140                   from, to);
141     }
142   else
143     {
144       static int shown;
145
146       if (!shown)
147         log_info (_("iconv_open failed: %s\n"), strerror (errno));
148       shown = 1;
149     }
150
151   if (use_fallback)
152     {
153       /* To avoid further error messages we fallback to Latin-1 for the
154          native encoding.  This is justified as one can expect that on a
155          utf-8 enabled system nl_langinfo() will work and thus we won't
156          never get to here.  Thus Latin-1 seems to be a reasonable
157          default.  */
158       active_charset_name = "iso-8859-1";
159       no_translation = 0;
160       use_iconv = 0;
161     }
162 }
163
164
165
166 int
167 set_native_charset (const char *newset)
168 {
169   const char *full_newset;
170
171   if (!newset)
172     {
173 #ifdef HAVE_W32_SYSTEM
174       static char codepage[30];
175       unsigned int cpno;
176       const char *aliases;
177
178       /* We are a console program thus we need to use the
179          GetConsoleOutputCP function and not the the GetACP which
180          would give the codepage for a GUI program.  Note this is not
181          a bulletproof detection because GetConsoleCP might return a
182          different one for console input.  Not sure how to cope with
183          that.  If the console Code page is not known we fall back to
184          the system code page.  */
185 #ifndef HAVE_W32CE_SYSTEM
186       cpno = GetConsoleOutputCP ();
187       if (!cpno)
188 #endif
189         cpno = GetACP ();
190       sprintf (codepage, "CP%u", cpno );
191       /* Resolve alias.  We use a long string string and not the usual
192          array to optimize if the code is taken to a DSO.  Taken from
193          libiconv 1.9.2. */
194       newset = codepage;
195       for (aliases = ("CP936"   "\0" "GBK" "\0"
196                       "CP1361"  "\0" "JOHAB" "\0"
197                       "CP20127" "\0" "ASCII" "\0"
198                       "CP20866" "\0" "KOI8-R" "\0"
199                       "CP21866" "\0" "KOI8-RU" "\0"
200                       "CP28591" "\0" "ISO-8859-1" "\0"
201                       "CP28592" "\0" "ISO-8859-2" "\0"
202                       "CP28593" "\0" "ISO-8859-3" "\0"
203                       "CP28594" "\0" "ISO-8859-4" "\0"
204                       "CP28595" "\0" "ISO-8859-5" "\0"
205                       "CP28596" "\0" "ISO-8859-6" "\0"
206                       "CP28597" "\0" "ISO-8859-7" "\0"
207                       "CP28598" "\0" "ISO-8859-8" "\0"
208                       "CP28599" "\0" "ISO-8859-9" "\0"
209                       "CP28605" "\0" "ISO-8859-15" "\0"
210                       "CP65001" "\0" "UTF-8" "\0");
211            *aliases;
212            aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
213         {
214           if (!strcmp (codepage, aliases) ||(*aliases == '*' && !aliases[1]))
215             {
216               newset = aliases + strlen (aliases) + 1;
217               break;
218             }
219         }
220
221 #else /*!HAVE_W32_SYSTEM*/
222
223 #ifdef HAVE_LANGINFO_CODESET
224       newset = nl_langinfo (CODESET);
225 #else /*!HAVE_LANGINFO_CODESET*/
226       /* Try to get the used charset from environment variables.  */
227       static char codepage[30];
228       const char *lc, *dot, *mod;
229
230       strcpy (codepage, "iso-8859-1");
231       lc = getenv ("LC_ALL");
232       if (!lc || !*lc)
233         {
234           lc = getenv ("LC_CTYPE");
235           if (!lc || !*lc)
236             lc = getenv ("LANG");
237         }
238       if (lc && *lc)
239         {
240           dot = strchr (lc, '.');
241           if (dot)
242             {
243               mod = strchr (++dot, '@');
244               if (!mod)
245                 mod = dot + strlen (dot);
246               if (mod - dot < sizeof codepage && dot != mod)
247                 {
248                   memcpy (codepage, dot, mod - dot);
249                   codepage [mod - dot] = 0;
250                 }
251             }
252         }
253       newset = codepage;
254 #endif /*!HAVE_LANGINFO_CODESET*/
255 #endif /*!HAVE_W32_SYSTEM*/
256     }
257
258   full_newset = newset;
259   if (strlen (newset) > 3 && !ascii_memcasecmp (newset, "iso", 3))
260     {
261       newset += 3;
262       if (*newset == '-' || *newset == '_')
263         newset++;
264     }
265
266   /* Note that we silently assume that plain ASCII is actually meant
267      as Latin-1.  This makes sense because many Unix system don't have
268      their locale set up properly and thus would get annoying error
269      messages and we have to handle all the "bug" reports. Latin-1 has
270      always been the character set used for 8 bit characters on Unix
271      systems. */
272   if ( !*newset
273        || !ascii_strcasecmp (newset, "8859-1" )
274        || !ascii_strcasecmp (newset, "646" )
275        || !ascii_strcasecmp (newset, "ASCII" )
276        || !ascii_strcasecmp (newset, "ANSI_X3.4-1968" )
277        )
278     {
279       active_charset_name = "iso-8859-1";
280       no_translation = 0;
281       use_iconv = 0;
282     }
283   else if ( !ascii_strcasecmp (newset, "utf8" )
284             || !ascii_strcasecmp(newset, "utf-8") )
285     {
286       active_charset_name = "utf-8";
287       no_translation = 1;
288       use_iconv = 0;
289     }
290   else
291     {
292       iconv_t cd;
293
294 #ifdef HAVE_W32_SYSTEM
295       if (load_libiconv ())
296         return -1;
297 #endif /*HAVE_W32_SYSTEM*/
298
299       cd = iconv_open (full_newset, "utf-8");
300       if (cd == (iconv_t)-1)
301         {
302           handle_iconv_error (full_newset, "utf-8", 0);
303           return -1;
304         }
305       iconv_close (cd);
306       cd = iconv_open ("utf-8", full_newset);
307       if (cd == (iconv_t)-1)
308         {
309           handle_iconv_error ("utf-8", full_newset, 0);
310           return -1;
311         }
312       iconv_close (cd);
313       active_charset_name = full_newset;
314       no_translation = 0;
315       use_iconv = 1;
316     }
317   return 0;
318 }
319
320 const char *
321 get_native_charset ()
322 {
323   return active_charset_name;
324 }
325
326 /* Return true if the native charset is utf-8.  */
327 int
328 is_native_utf8 (void)
329 {
330   return no_translation;
331 }
332
333
334 /* Convert string, which is in native encoding to UTF8 and return a
335    new allocated UTF-8 string.  This function terminates the process
336    on memory shortage.  */
337 char *
338 native_to_utf8 (const char *orig_string)
339 {
340   const unsigned char *string = (const unsigned char *)orig_string;
341   const unsigned char *s;
342   char *buffer;
343   unsigned char *p;
344   size_t length = 0;
345
346   if (no_translation)
347     {
348       /* Already utf-8 encoded. */
349       buffer = jnlib_xstrdup (orig_string);
350     }
351   else if (!use_iconv)
352     {
353       /* For Latin-1 we can avoid the iconv overhead. */
354       for (s = string; *s; s++)
355         {
356           length++;
357           if (*s & 0x80)
358             length++;
359         }
360       buffer = jnlib_xmalloc (length + 1);
361       for (p = (unsigned char *)buffer, s = string; *s; s++)
362         {
363           if ( (*s & 0x80 ))
364             {
365               *p++ = 0xc0 | ((*s >> 6) & 3);
366               *p++ = 0x80 | (*s & 0x3f);
367             }
368           else
369             *p++ = *s;
370         }
371       *p = 0;
372     }
373   else
374     {
375       /* Need to use iconv.  */
376       iconv_t cd;
377       const char *inptr;
378       char *outptr;
379       size_t inbytes, outbytes;
380
381       cd = iconv_open ("utf-8", active_charset_name);
382       if (cd == (iconv_t)-1)
383         {
384           handle_iconv_error ("utf-8", active_charset_name, 1);
385           return native_to_utf8 (string);
386         }
387
388       for (s=string; *s; s++ )
389         {
390           length++;
391           if ((*s & 0x80))
392             length += 5; /* We may need up to 6 bytes for the utf8 output. */
393         }
394       buffer = jnlib_xmalloc (length + 1);
395
396       inptr = string;
397       inbytes = strlen (string);
398       outptr = buffer;
399       outbytes = length;
400       if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
401                   &outptr, &outbytes) == (size_t)-1)
402         {
403           static int shown;
404
405           if (!shown)
406             log_info (_("conversion from `%s' to `%s' failed: %s\n"),
407                       active_charset_name, "utf-8", strerror (errno));
408           shown = 1;
409           /* We don't do any conversion at all but use the strings as is. */
410           strcpy (buffer, string);
411         }
412       else /* Success.  */
413         {
414           *outptr = 0;
415           /* We could realloc the buffer now but I doubt that it makes
416              much sense given that it will get freed anyway soon
417              after.  */
418         }
419       iconv_close (cd);
420     }
421   return buffer;
422 }
423
424
425
426 static char *
427 do_utf8_to_native (const char *string, size_t length, int delim,
428                    int with_iconv)
429 {
430   int nleft;
431   int i;
432   unsigned char encbuf[8];
433   int encidx;
434   const unsigned char *s;
435   size_t n;
436   char *buffer = NULL;
437   char *p = NULL;
438   unsigned long val = 0;
439   size_t slen;
440   int resync = 0;
441
442   /* First pass (p==NULL): count the extended utf-8 characters.  */
443   /* Second pass (p!=NULL): create string.  */
444   for (;;)
445     {
446       for (slen = length, nleft = encidx = 0, n = 0,
447              s = (const unsigned char *)string;
448            slen;
449            s++, slen--)
450         {
451           if (resync)
452             {
453               if (!(*s < 128 || (*s >= 0xc0 && *s <= 0xfd)))
454                 {
455                   /* Still invalid. */
456                   if (p)
457                     {
458                       sprintf (p, "\\x%02x", *s);
459                       p += 4;
460                     }
461                   n += 4;
462                   continue;
463                 }
464               resync = 0;
465             }
466           if (!nleft)
467             {
468               if (!(*s & 0x80))
469                 {
470                   /* Plain ascii. */
471                   if ( delim != -1
472                        && (*s < 0x20 || *s == 0x7f || *s == delim
473                            || (delim && *s == '\\')))
474                     {
475                       n++;
476                       if (p)
477                         *p++ = '\\';
478                       switch (*s)
479                         {
480                         case '\n': n++; if ( p ) *p++ = 'n'; break;
481                         case '\r': n++; if ( p ) *p++ = 'r'; break;
482                         case '\f': n++; if ( p ) *p++ = 'f'; break;
483                         case '\v': n++; if ( p ) *p++ = 'v'; break;
484                         case '\b': n++; if ( p ) *p++ = 'b'; break;
485                         case    0: n++; if ( p ) *p++ = '0'; break;
486                         default:
487                           n += 3;
488                           if (p)
489                             {
490                               sprintf (p, "x%02x", *s);
491                               p += 3;
492                             }
493                           break;
494                         }
495                     }
496                   else
497                     {
498                       if (p)
499                         *p++ = *s;
500                       n++;
501                     }
502                 }
503               else if ((*s & 0xe0) == 0xc0) /* 110x xxxx */
504                 {
505                   val = *s & 0x1f;
506                   nleft = 1;
507                   encidx = 0;
508                   encbuf[encidx++] = *s;
509                 }
510               else if ((*s & 0xf0) == 0xe0) /* 1110 xxxx */
511                 {
512                   val = *s & 0x0f;
513                   nleft = 2;
514                   encidx = 0;
515                   encbuf[encidx++] = *s;
516                 }
517               else if ((*s & 0xf8) == 0xf0) /* 1111 0xxx */
518                 {
519                   val = *s & 0x07;
520                   nleft = 3;
521                   encidx = 0;
522                   encbuf[encidx++] = *s;
523                 }
524               else if ((*s & 0xfc) == 0xf8) /* 1111 10xx */
525                 {
526                   val = *s & 0x03;
527                   nleft = 4;
528                   encidx = 0;
529                   encbuf[encidx++] = *s;
530                 }
531               else if ((*s & 0xfe) == 0xfc) /* 1111 110x */
532                 {
533                   val = *s & 0x01;
534                   nleft = 5;
535                   encidx = 0;
536                   encbuf[encidx++] = *s;
537                 }
538               else /* Invalid encoding: print as \xNN. */
539                 {
540                   if (p)
541                     {
542                       sprintf (p, "\\x%02x", *s);
543                       p += 4;
544                     }
545                   n += 4;
546                   resync = 1;
547                 }
548             }
549           else if (*s < 0x80 || *s >= 0xc0) /* Invalid utf-8 */
550             {
551               if (p)
552                 {
553                   for (i = 0; i < encidx; i++)
554                     {
555                       sprintf (p, "\\x%02x", encbuf[i]);
556                       p += 4;
557                     }
558                   sprintf (p, "\\x%02x", *s);
559                   p += 4;
560                 }
561               n += 4 + 4 * encidx;
562               nleft = 0;
563               encidx = 0;
564               resync = 1;
565             }
566           else
567             {
568               encbuf[encidx++] = *s;
569               val <<= 6;
570               val |= *s & 0x3f;
571               if (!--nleft)  /* Ready. */
572                 {
573                   if (no_translation)
574                     {
575                       if (p)
576                         {
577                           for (i = 0; i < encidx; i++)
578                             *p++ = encbuf[i];
579                         }
580                       n += encidx;
581                       encidx = 0;
582                     }
583                   else if (with_iconv)
584                     {
585                       /* Our strategy for using iconv is a bit strange
586                          but it better keeps compatibility with
587                          previous versions in regard to how invalid
588                          encodings are displayed.  What we do is to
589                          keep the utf-8 as is and have the real
590                          translation step then at the end.  Yes, I
591                          know that this is ugly.  However we are short
592                          of the 1.4 release and for this branch we
593                          should not mess too much around with iconv
594                          things.  One reason for this is that we don't
595                          know enough about non-GNU iconv
596                          implementation and want to minimize the risk
597                          of breaking the code on too many platforms.  */
598                         if ( p )
599                           {
600                             for (i=0; i < encidx; i++ )
601                               *p++ = encbuf[i];
602                           }
603                         n += encidx;
604                         encidx = 0;
605                     }
606                   else  /* Latin-1 case. */
607                     {
608                       if (val >= 0x80 && val < 256)
609                         {
610                           /* We can simply print this character */
611                           n++;
612                           if (p)
613                             *p++ = val;
614                         }
615                       else
616                         {
617                           /* We do not have a translation: print utf8. */
618                           if (p)
619                             {
620                               for (i = 0; i < encidx; i++)
621                                 {
622                                   sprintf (p, "\\x%02x", encbuf[i]);
623                                   p += 4;
624                                 }
625                             }
626                           n += encidx * 4;
627                           encidx = 0;
628                         }
629                     }
630                 }
631
632             }
633         }
634       if (!buffer)
635         {
636           /* Allocate the buffer after the first pass. */
637           buffer = p = jnlib_xmalloc (n + 1);
638         }
639       else if (with_iconv)
640         {
641           /* Note: See above for comments.  */
642           iconv_t cd;
643           const char *inptr;
644           char *outbuf, *outptr;
645           size_t inbytes, outbytes;
646
647           *p = 0;  /* Terminate the buffer. */
648
649           cd = iconv_open (active_charset_name, "utf-8");
650           if (cd == (iconv_t)-1)
651             {
652               handle_iconv_error (active_charset_name, "utf-8", 1);
653               jnlib_free (buffer);
654               return utf8_to_native (string, length, delim);
655             }
656
657           /* Allocate a new buffer large enough to hold all possible
658              encodings. */
659           n = p - buffer + 1;
660           inbytes = n - 1;;
661           inptr = buffer;
662           outbytes = n * MB_LEN_MAX;
663           if (outbytes / MB_LEN_MAX != n)
664             BUG (); /* Actually an overflow. */
665           outbuf = outptr = jnlib_xmalloc (outbytes);
666           if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes,
667                       &outptr, &outbytes) == (size_t)-1)
668             {
669               static int shown;
670
671               if (!shown)
672                 log_info (_("conversion from `%s' to `%s' failed: %s\n"),
673                           "utf-8", active_charset_name, strerror (errno));
674               shown = 1;
675               /* Didn't worked out.  Try again but without iconv.  */
676               jnlib_free (buffer);
677               buffer = NULL;
678               jnlib_free (outbuf);
679               outbuf = do_utf8_to_native (string, length, delim, 0);
680             }
681             else /* Success.  */
682               {
683                 *outptr = 0; /* Make sure it is a string. */
684                 /* We could realloc the buffer now but I doubt that it
685                    makes much sense given that it will get freed
686                    anyway soon after.  */
687                 jnlib_free (buffer);
688               }
689           iconv_close (cd);
690           return outbuf;
691         }
692       else /* Not using iconv. */
693         {
694           *p = 0; /* Make sure it is a string. */
695           return buffer;
696         }
697     }
698 }
699
700 /* Convert string, which is in UTF-8 to native encoding.  Replace
701    illegal encodings by some "\xnn" and quote all control
702    characters. A character with value DELIM will always be quoted, it
703    must be a vanilla ASCII character.  A DELIM value of -1 is special:
704    it disables all quoting of control characters.  This function
705    terminates the process on memory shortage.  */
706 char *
707 utf8_to_native (const char *string, size_t length, int delim)
708 {
709   return do_utf8_to_native (string, length, delim, use_iconv);
710 }
711
712
713
714
715 /* Wrapper function for iconv_open, required for W32 as we dlopen that
716    library on that system.  */
717 jnlib_iconv_t
718 jnlib_iconv_open (const char *tocode, const char *fromcode)
719 {
720 #ifdef HAVE_W32_SYSTEM
721   if (load_libiconv ())
722     return (jnlib_iconv_t)(-1);
723 #endif /*HAVE_W32_SYSTEM*/
724
725   return (jnlib_iconv_t)iconv_open (tocode, fromcode);
726 }
727
728
729 /* Wrapper function for iconv, required for W32 as we dlopen that
730    library on that system.  */
731 size_t
732 jnlib_iconv (jnlib_iconv_t cd,
733              const char **inbuf, size_t *inbytesleft,
734              char **outbuf, size_t *outbytesleft)
735 {
736
737 #ifdef HAVE_W32_SYSTEM
738   if (load_libiconv ())
739     return 0;
740 #endif /*HAVE_W32_SYSTEM*/
741
742   return iconv ((iconv_t)cd, (char**)inbuf, inbytesleft, outbuf, outbytesleft);
743 }
744
745 /* Wrapper function for iconv_close, required for W32 as we dlopen that
746    library on that system.  */
747 int
748 jnlib_iconv_close (jnlib_iconv_t cd)
749 {
750 #ifdef HAVE_W32_SYSTEM
751   if (load_libiconv ())
752     return 0;
753 #endif /*HAVE_W32_SYSTEM*/
754
755   return iconv_close ((iconv_t)cd);
756 }
757
758
759 #ifdef HAVE_W32_SYSTEM
760 /* Return a malloced string encoded in UTF-8 from the wide char input
761    string STRING.  Caller must free this value.  Returns NULL and sets
762    ERRNO on failure.  Calling this function with STRING set to NULL is
763    not defined.  */
764 char *
765 wchar_to_utf8 (const wchar_t *string)
766 {
767   int n;
768   char *result;
769
770   n = WideCharToMultiByte (CP_UTF8, 0, string, -1, NULL, 0, NULL, NULL);
771   if (n < 0)
772     {
773       jnlib_set_errno (EINVAL);
774       return NULL;
775     }
776
777   result = jnlib_malloc (n+1);
778   if (!result)
779     return NULL;
780
781   n = WideCharToMultiByte (CP_UTF8, 0, string, -1, result, n, NULL, NULL);
782   if (n < 0)
783     {
784       jnlib_free (result);
785       jnlib_set_errno (EINVAL);
786       result = NULL;
787     }
788   return result;
789 }
790
791
792 /* Return a malloced wide char string from an UTF-8 encoded input
793    string STRING.  Caller must free this value.  Returns NULL and sets
794    ERRNO on failure.  Calling this function with STRING set to NULL is
795    not defined.  */
796 wchar_t *
797 utf8_to_wchar (const char *string)
798 {
799   int n;
800   size_t nbytes;
801   wchar_t *result;
802
803   n = MultiByteToWideChar (CP_UTF8, 0, string, -1, NULL, 0);
804   if (n < 0)
805     {
806       jnlib_set_errno (EINVAL);
807       return NULL;
808     }
809
810   nbytes = (size_t)(n+1) * sizeof(*result);
811   if (nbytes / sizeof(*result) != (n+1))
812     {
813       jnlib_set_errno (ENOMEM);
814       return NULL;
815     }
816   result = jnlib_malloc (nbytes);
817   if (!result)
818     return NULL;
819
820   n = MultiByteToWideChar (CP_UTF8, 0, string, -1, result, n);
821   if (n < 0)
822     {
823       free (result);
824       jnlib_set_errno (EINVAL);
825       result = NULL;
826     }
827   return result;
828 }
829 #endif /*HAVE_W32_SYSTEM*/