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