]> arthur.barton.de Git - netatalk.git/commitdiff
some unicode fixes
authorbfernhomberg <bfernhomberg>
Fri, 14 Nov 2003 23:41:04 +0000 (23:41 +0000)
committerbfernhomberg <bfernhomberg>
Fri, 14 Nov 2003 23:41:04 +0000 (23:41 +0000)
include/atalk/unicode.h
libatalk/unicode/charcnv.c
libatalk/unicode/charsets/generic_mb.c
libatalk/unicode/iconv.c
libatalk/unicode/util_unistr.c

index 90ec8822e04dd17b668382f4592566360e769b33..cccfe15385864107523057f0e878b0490f24f41a 100644 (file)
@@ -123,6 +123,7 @@ extern size_t       charset_to_ucs2_allocate __P((charset_t, ucs2_t **dest, const cha
 extern size_t  charset_to_utf8_allocate __P((charset_t, char **dest, const char *src));
 extern size_t  ucs2_to_charset_allocate __P((charset_t, char **dest, const ucs2_t *src));
 extern size_t  utf8_to_charset_allocate __P((charset_t, char **dest, const char *src));
+extern size_t  ucs2_to_charset __P((charset_t, const ucs2_t *src, char *dest, size_t));
 
 extern size_t  convert_charset __P((charset_t, charset_t, charset_t, char *, size_t, char *, size_t, u_int16_t *));
 
index c6dd068e5ad5869f2b41f566f1ac437bf8c5909f..157b9220ee55ab745093c476e352a1f5585b0d68 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
-#include <sys/param.h>
 #include <ctype.h>
-#include <sys/stat.h>
-#include <atalk/logger.h>
 #include <errno.h>
-
-#include <netatalk/endian.h>
-#include <atalk/unicode.h>
-
+#include <sys/stat.h>
+#include <sys/param.h>
 #ifdef HAVE_USABLE_ICONV
 #include <iconv.h>
 #endif
-
 #if HAVE_LOCALE_H
 #include <locale.h>
 #endif
-
 #if HAVE_LANGINFO_H
 #include <langinfo.h>
 #endif
+
+#include <netatalk/endian.h>
+#include <atalk/logger.h>
+#include <atalk/unicode.h>
 #include "byteorder.h"
 
 
@@ -206,11 +203,13 @@ void init_iconv(void)
 
        /* so that charset_name() works we need to get the UNIX<->UCS2 going
           first */
+#if 0
        if (!conv_handles[CH_UNIX][CH_UCS2])
                conv_handles[CH_UNIX][CH_UCS2] = atalk_iconv_open("UCS-2", "ASCII");
 
        if (!conv_handles[CH_UCS2][CH_UNIX])
                conv_handles[CH_UCS2][CH_UNIX] = atalk_iconv_open("ASCII", "UCS-2");
+#endif
 
        for (c1=0;c1<NUM_CHARSETS;c1++) {
                const char *name = charset_name((charset_t)c1);
@@ -280,7 +279,7 @@ static size_t convert_string_internal(charset_t from, charset_t to,
                               reason="Illegal multibyte sequence";
                               break;
                }
-               LOG(log_debug, logtype_default,"Conversion error: %s(%s)\n",reason,inbuf);
+               LOG(log_debug, logtype_default,"Conversion error: %s",reason);
                return (size_t)-1;
        }
 
@@ -289,8 +288,11 @@ static size_t convert_string_internal(charset_t from, charset_t to,
                o_save[destlen-o_len]   = 0;
                o_save[destlen-o_len+1] = 0;
        }
-       else if ( destlen-o_len > 0)
+       else if ( to != CH_UCS2 && destlen-o_len > 0 )
                o_save[destlen-o_len] = 0;
+       else {
+               /* FIXME: what should we do here, string *might* be unterminated. E2BIG? */
+       }
 
        return destlen-o_len;
 }
@@ -301,15 +303,16 @@ size_t convert_string(charset_t from, charset_t to,
                      void *dest, size_t destlen)
 {
        size_t i_len, o_len;
-       char *u;
-       char buffer[MAXPATHLEN];
-       char buffer2[MAXPATHLEN];
+       ucs2_t *u;
+       ucs2_t buffer[MAXPATHLEN];
+       ucs2_t buffer2[MAXPATHLEN];
        int composition = 0;
 
        lazy_initialize_conv();
 
        /* convert from_set to UCS2 */
-       if ((size_t)(-1) == ( o_len = convert_string_internal( from, CH_UCS2, src, srclen, buffer, MAXPATHLEN)) ) {
+       if ((size_t)(-1) == ( o_len = convert_string_internal( from, CH_UCS2, src, srclen, 
+                                                               (char*) buffer, sizeof(buffer))) ) {
                LOG(log_error, logtype_default, "Conversion failed ( %s to CH_UCS2 )", charset_name(from));
                return (size_t) -1;
        }
@@ -321,7 +324,7 @@ size_t convert_string(charset_t from, charset_t to,
        if ((charsets[to] && charsets[to]->flags & CHARSET_DECOMPOSED) )
            composition = 2;
  
-       i_len = MAXPATHLEN;
+       i_len = sizeof(buffer2);
        u = buffer2;
 
        switch (composition) {
@@ -330,17 +333,17 @@ size_t convert_string(charset_t from, charset_t to,
            i_len = o_len;
            break;
        case 1:
-            if ( (size_t)-1 == (i_len = precompose_w((ucs2_t *)buffer, o_len, (ucs2_t *)u, &i_len)) )
+            if ( (size_t)-1 == (i_len = precompose_w(buffer, o_len, u, &i_len)) )
                return (size_t)(-1);
            break;
        case 2:
-            if ( (size_t)-1 == (i_len = decompose_w((ucs2_t *)buffer, o_len, (ucs2_t *)u, &i_len)) )
+            if ( (size_t)-1 == (i_len = decompose_w(buffer, o_len, u, &i_len)) )
                return (size_t)(-1);
            break;
        }
                
        /* Convert UCS2 to to_set */
-       if ((size_t)(-1) == ( o_len = convert_string_internal( CH_UCS2, to, u, i_len, dest, destlen)) ) {
+       if ((size_t)(-1) == ( o_len = convert_string_internal( CH_UCS2, to, (char*) u, i_len, dest, destlen)) ) {
                LOG(log_error, logtype_default, "Conversion failed (CH_UCS2 to %s):%s", charset_name(to), strerror(errno));
                return (size_t) -1;
        }
@@ -366,7 +369,7 @@ static size_t convert_string_allocate_internal(charset_t from, charset_t to,
        size_t i_len, o_len, destlen;
        size_t retval;
        const char *inbuf = (const char *)src;
-       char *outbuf, *ob;
+       char *outbuf = NULL, *ob = NULL;
        atalk_iconv_t descriptor;
 
        *dest = NULL;
@@ -385,10 +388,9 @@ static size_t convert_string_allocate_internal(charset_t from, charset_t to,
        }
 
        destlen = MAX(srclen, 512);
-       outbuf = NULL;
 convert:
        destlen = destlen * 2;
-       ob = (char *)realloc(outbuf, destlen);
+       ob = (char *)realloc(ob, destlen);
        if (!ob) {
                LOG(log_debug, logtype_default,"convert_string_allocate: realloc failed!\n");
                SAFE_FREE(outbuf);
@@ -396,6 +398,7 @@ convert:
        } else {
                outbuf = ob;
        }
+       inbuf = src;   /* this restarts the whole conversion if buffer needed to be increased */
        i_len = srclen;
        o_len = destlen;
        retval = atalk_iconv(descriptor,
@@ -413,8 +416,7 @@ convert:
                                reason="Illegal multibyte sequence";
                                break;
                }
-               LOG(log_debug, logtype_default,"Conversion error: %s(%s)\n",reason,inbuf);
-               /* smb_panic(reason); */
+               LOG(log_debug, logtype_default,"Conversion error: %s(%s)",reason,inbuf);
                return (size_t)-1;
        }
 
@@ -422,15 +424,18 @@ convert:
        destlen = destlen - o_len;
 
        /* Terminate the string */
-       if (to == CH_UCS2 && destlen-o_len >= 2) {
+       if (to == CH_UCS2 && o_len >= 2) {
                ob[destlen] = 0;
                ob[destlen+1] = 0;
                *dest = (char *)realloc(ob,destlen+2);
        }
-       else if ( destlen-o_len > 0) {
+       else if ( to != CH_UCS2 && o_len > 0 ) {
                ob[destlen] = 0;
                *dest = (char *)realloc(ob,destlen+1);
        }
+       else {
+               goto convert; /* realloc */
+       }
 
        if (destlen && !*dest) {
                LOG(log_debug, logtype_default, "convert_string_allocate: out of memory!\n");
@@ -447,15 +452,18 @@ size_t convert_string_allocate(charset_t from, charset_t to,
                      char ** dest)
 {
        size_t i_len, o_len;
-       char *u;
-       char buffer[MAXPATHLEN];
-       char buffer2[MAXPATHLEN];
+       ucs2_t *u;
+       ucs2_t buffer[MAXPATHLEN];
+       ucs2_t buffer2[MAXPATHLEN];
        int composition = 0;
 
        lazy_initialize_conv();
 
+       *dest = NULL;
+
        /* convert from_set to UCS2 */
-       if ((size_t)(-1) == ( o_len = convert_string_internal( from, CH_UCS2, src, srclen, buffer, MAXPATHLEN)) ) {
+       if ((size_t)(-1) == ( o_len = convert_string_internal( from, CH_UCS2, src, srclen, 
+                                                               buffer, sizeof(buffer))) ) {
                LOG(log_error, logtype_default, "Conversion failed ( %s to CH_UCS2 )", charset_name(from));
                return (size_t) -1;
        }
@@ -467,7 +475,7 @@ size_t convert_string_allocate(charset_t from, charset_t to,
        if ((charsets[to] && charsets[to]->flags & CHARSET_DECOMPOSED) )
            composition = 2;
  
-       i_len = MAXPATHLEN;
+       i_len = sizeof(buffer2);
        u = buffer2;
 
        switch (composition) {
@@ -476,17 +484,17 @@ size_t convert_string_allocate(charset_t from, charset_t to,
            i_len = o_len;
            break;
        case 1:
-            if ( (size_t)-1 == (i_len = precompose_w((ucs2_t *)buffer, o_len, (ucs2_t *)u, &i_len)) )
+            if ( (size_t)-1 == (i_len = precompose_w(buffer, o_len, u, &i_len)) )
                return (size_t)(-1);
            break;
        case 2:
-            if ( (size_t)-1 == (i_len = decompose_w((ucs2_t *)buffer, o_len, (ucs2_t *)u, &i_len)) )
+            if ( (size_t)-1 == (i_len = decompose_w(buffer, o_len, u, &i_len)) )
                return (size_t)(-1);
            break;
        }
                
        /* Convert UCS2 to to_set */
-       if ((size_t)(-1) == ( o_len = convert_string_allocate_internal( CH_UCS2, to, u, i_len, dest)) ) 
+       if ((size_t)(-1) == ( o_len = convert_string_allocate_internal( CH_UCS2, to, (char*)u, i_len, dest)) ) 
                LOG(log_error, logtype_default, "Conversion failed (CH_UCS2 to %s):%s", charset_name(to), strerror(errno));
                
        return o_len;
@@ -501,7 +509,7 @@ size_t charset_strupper(charset_t ch, const char *src, size_t srclen, char *dest
        size = convert_string_allocate_internal(ch, CH_UCS2, src, srclen,
                                       (char**) &buffer);
        if (size == (size_t)-1) {
-               free(buffer);
+               SAFE_FREE(buffer);
                return size;
        }
        if (!strupper_w((ucs2_t *)buffer) && (dest == src)) {
@@ -522,7 +530,7 @@ size_t charset_strlower(charset_t ch, const char *src, size_t srclen, char *dest
        size = convert_string_allocate_internal(ch, CH_UCS2, src, srclen,
                                       (char **) &buffer);
        if (size == (size_t)-1) {
-               free(buffer);
+               SAFE_FREE(buffer);
                return size;
        }
        if (!strlower_w((ucs2_t *)buffer) && (dest == src)) {
@@ -567,7 +575,7 @@ size_t utf8_strlower(const char *src, size_t srclen, char *dest, size_t destlen)
 
 size_t charset_to_ucs2_allocate(charset_t ch, ucs2_t **dest, const char *src)
 {
-       size_t src_len = strlen(src)+1;
+       size_t src_len = strlen(src);
 
        *dest = NULL;
        return convert_string_allocate(ch, CH_UCS2, src, src_len, (char**) dest);       
@@ -583,7 +591,7 @@ size_t charset_to_ucs2_allocate(charset_t ch, ucs2_t **dest, const char *src)
 
 size_t charset_to_utf8_allocate(charset_t ch, char **dest, const char *src)
 {
-       size_t src_len = strlen(src)+1;
+       size_t src_len = strlen(src);
 
        *dest = NULL;
        return convert_string_allocate(ch, CH_UTF8, src, src_len, dest);        
@@ -597,9 +605,16 @@ size_t charset_to_utf8_allocate(charset_t ch, char **dest, const char *src)
  * @returns The number of bytes occupied by the string in the destination
  **/
 
+size_t ucs2_to_charset(charset_t ch, const ucs2_t *src, char *dest, size_t destlen)
+{
+       size_t src_len = (strlen_w(src)) * sizeof(ucs2_t);
+       return convert_string(CH_UCS2, ch, src, src_len, dest, destlen);        
+}
+
+
 size_t ucs2_to_charset_allocate(charset_t ch, char **dest, const ucs2_t *src)
 {
-       size_t src_len = (strlen_w(src)+1) * sizeof(ucs2_t);
+       size_t src_len = (strlen_w(src)) * sizeof(ucs2_t);
        *dest = NULL;
        return convert_string_allocate(CH_UCS2, ch, src, src_len, dest);        
 }
@@ -614,7 +629,7 @@ size_t ucs2_to_charset_allocate(charset_t ch, char **dest, const ucs2_t *src)
 
 size_t utf8_to_charset_allocate(charset_t ch, char **dest, const char *src)
 {
-       size_t src_len = strlen(src)+1;
+       size_t src_len = strlen(src);
        *dest = NULL;
        return convert_string_allocate(CH_UTF8, ch, src, src_len, dest);        
 }
@@ -622,21 +637,21 @@ size_t utf8_to_charset_allocate(charset_t ch, char **dest, const char *src)
 size_t charset_precompose ( charset_t ch, char * src, size_t inlen, char * dst, size_t outlen)
 {
        char *buffer;
-       char u[MAXPATHLEN];
+       ucs2_t u[MAXPATHLEN];
        size_t len;
        size_t ilen;
 
         if ((size_t)(-1) == (len = convert_string_allocate_internal(ch, CH_UCS2, src, inlen, &buffer)) )
             return len;
 
-       ilen=MAXPATHLEN;
+       ilen=sizeof(u);
 
-       if ( (size_t)-1 == (ilen = precompose_w((ucs2_t *)buffer, len, (ucs2_t *)u, &ilen)) ) {
+       if ( (size_t)-1 == (ilen = precompose_w((ucs2_t *)buffer, len, u, &ilen)) ) {
            free (buffer);
            return (size_t)(-1);
        }
 
-        if ((size_t)(-1) == (len = convert_string_internal( CH_UCS2, ch, u, ilen, dst, outlen)) ) {
+        if ((size_t)(-1) == (len = convert_string_internal( CH_UCS2, ch, (char*)u, ilen, dst, outlen)) ) {
            free (buffer);
            return (size_t)(-1);
        }
@@ -649,21 +664,21 @@ size_t charset_precompose ( charset_t ch, char * src, size_t inlen, char * dst,
 size_t charset_decompose ( charset_t ch, char * src, size_t inlen, char * dst, size_t outlen)
 {
        char *buffer;
-       char u[MAXPATHLEN];
+       ucs2_t u[MAXPATHLEN];
        size_t len;
        size_t ilen;
 
         if ((size_t)(-1) == (len = convert_string_allocate_internal(ch, CH_UCS2, src, inlen, &buffer)) )
             return len;
 
-       ilen=MAXPATHLEN;
+       ilen=sizeof(u);
 
-       if ( (size_t)-1 == (ilen = decompose_w((ucs2_t *)buffer, len, (ucs2_t *)u, &ilen)) ) {
+       if ( (size_t)-1 == (ilen = decompose_w((ucs2_t *)buffer, len, u, &ilen)) ) {
            free (buffer);
            return (size_t)(-1);
        }
 
-        if ((size_t)(-1) == (len = convert_string_internal( CH_UCS2, ch, u, ilen, dst, outlen)) ) {
+        if ((size_t)(-1) == (len = convert_string_internal( CH_UCS2, ch, (char*)u, ilen, dst, outlen)) ) {
            free (buffer);
            return (size_t)(-1);
        }
@@ -942,15 +957,16 @@ escape_slash:
 size_t convert_charset ( charset_t from_set, charset_t to_set, charset_t cap_charset, char* src, size_t src_len, char* dest, size_t dest_len, u_int16_t *flags)
 {
        size_t i_len, o_len;
-       char *u;
-       char buffer[MAXPATHLEN];
-       char buffer2[MAXPATHLEN];
+       ucs2_t *u;
+       ucs2_t buffer[MAXPATHLEN];
+       ucs2_t buffer2[MAXPATHLEN];
        int composition = 0;
        
        lazy_initialize_conv();
 
        /* convert from_set to UCS2 */
-       if ((size_t)(-1) == ( o_len = pull_charset_flags( from_set, cap_charset, src, src_len, buffer, MAXPATHLEN, flags)) ) {
+       if ((size_t)(-1) == ( o_len = pull_charset_flags( from_set, cap_charset, src, src_len, 
+                                                          (char *) buffer, sizeof(buffer), flags)) ) {
                LOG(log_error, logtype_default, "Conversion failed ( %s to CH_UCS2 )", charset_name(from_set));
                return (size_t) -1;
        }
@@ -966,7 +982,7 @@ size_t convert_charset ( charset_t from_set, charset_t to_set, charset_t cap_cha
        if (CHECK_FLAGS(flags, CONV_DECOMPOSE) || (charsets[to_set] && charsets[to_set]->flags & CHARSET_DECOMPOSED) )
            composition = 2;
  
-       i_len = MAXPATHLEN;
+       i_len = sizeof(buffer2);
        u = buffer2;
 
        switch (composition) {
@@ -975,27 +991,27 @@ size_t convert_charset ( charset_t from_set, charset_t to_set, charset_t cap_cha
            i_len = o_len;
            break;
        case 1:
-            if ( (size_t)-1 == (i_len = precompose_w((ucs2_t *)buffer, o_len, (ucs2_t *)u, &i_len)) )
+            if ( (size_t)-1 == (i_len = precompose_w(buffer, o_len, u, &i_len)) )
                return (size_t)(-1);
            break;
        case 2:
-            if ( (size_t)-1 == (i_len = decompose_w((ucs2_t *)buffer, o_len, (ucs2_t *)u, &i_len)) )
+            if ( (size_t)-1 == (i_len = decompose_w(buffer, o_len, u, &i_len)) )
                return (size_t)(-1);
            break;
        }
                
        /* Do case conversions */       
        if (CHECK_FLAGS(flags, CONV_TOUPPER)) {
-           if (!strupper_w((ucs2_t *) u)) 
+           if (!strupper_w(u)) 
                return (size_t)(-1);
        }
        if (CHECK_FLAGS(flags, CONV_TOLOWER)) {
-           if (!strlower_w((ucs2_t *) u)) 
+           if (!strlower_w(u)) 
                return (size_t)(-1);
        }
 
        /* Convert UCS2 to to_set */
-       if ((size_t)(-1) == ( o_len = push_charset_flags( to_set, cap_charset, u, i_len, dest, dest_len, flags )) ) {
+       if ((size_t)(-1) == ( o_len = push_charset_flags( to_set, cap_charset, (char *)u, i_len, dest, dest_len, flags )) ) {
                LOG(log_error, logtype_default, 
                       "Conversion failed (CH_UCS2 to %s):%s", charset_name(to_set), strerror(errno));
                return (size_t) -1;
index cce7c46c4899be4008d79ba393aeb25b3b77d389..11f82c884d97e8a1691fc9cc09c6b9847b5f514f 100644 (file)
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#include <errno.h>
 
 #include <netatalk/endian.h>
 #include <atalk/unicode.h>
 #include <atalk/logger.h>
-#include <errno.h>
 
 #include "generic_mb.h"
 #include "../byteorder.h"
index fdc0e53dd5303c174b3890014a6395ac65205b1c..5c9511e5371cd38e8ee8fa49f87178e5ed180f16 100644 (file)
 #include <unistd.h>
 #include <string.h>
 #include <ctype.h>
+#include <errno.h>
 #include <sys/param.h>
 #include <sys/stat.h>
-#include <atalk/logger.h>
-#include <errno.h>
-
-#include <netatalk/endian.h>
-#include <atalk/unicode.h>
-
 #ifdef HAVE_USABLE_ICONV
 #include <iconv.h>
 #endif
+
+#include <netatalk/endian.h>
+#include <atalk/unicode.h>
+#include <atalk/logger.h>
 #include "byteorder.h"
 
 
@@ -92,7 +91,7 @@ struct charset_functions charset_ucs2 =
         0,
         iconv_copy,
         iconv_copy,
-        CHARSET_WIDECHAR
+        CHARSET_WIDECHAR | CHARSET_PRECOMPOSED
 };
 
 struct charset_functions charset_ascii =
index 92ee1b3f736c4d1fd8e8ad4ef965825f24b8dd9b..3e498dc9558e9167165189e5722ce17b5974d3a0 100644 (file)
@@ -394,7 +394,8 @@ size_t precompose_w (ucs2_t *name, size_t inplen, ucs2_t *comp, size_t *outlen)
                i += 2;
                in++;
                if (i == inplen) {
-                       *out++ = base;
+                       *out = base;
+                       out++;
                        *out = 0;
                        *outlen -= 2;
                        return o_len - *outlen;
@@ -450,10 +451,10 @@ size_t decompose_w (ucs2_t *name, size_t inplen, ucs2_t *comp, size_t *outlen)
                        /* exclude these ranges from decomposition according to AFP 3.1 spec */
                        /* page 97 */
                        *out = base;
-                       *out++;
+                       out++;
                        *outlen -= 2;
                }
-               if ((result = do_decomposition(base))) {
+               else if ((result = do_decomposition(base))) {
                        if ( *outlen < 4 ) {
                                errno = E2BIG;
                                return (size_t)-1;