~n-muench/ubuntu/oneiric/open-vm-tools/open-vm-tools.fix-836277

« back to all changes in this revision

Viewing changes to lib/unicode/unicodeSimpleBase.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-15 21:21:40 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080815212140-05fhxj8wroosysmj
Tags: 2008.08.08-109361-1ubuntu1
* Merge from Debian unstable (LP: #258393), remaining Ubuntu change:
  - add ubuntu_toolchain_FTBFS.dpatch patch, fix FTBFS
* Update ubuntu_toolchain_FTBFS.dpatch patch for the new version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
#include "unicodeBase.h"
44
44
#include "unicodeInt.h"
45
45
 
 
46
 
46
47
/*
47
48
 * Padding for initial and final bytes used by an encoding.  The value
48
49
 * comes from ICU's UCNV_GET_MAX_BYTES_FOR_STRING macro and accounts
49
50
 * for leading and trailing bytes and NUL.
50
51
 */
 
52
 
51
53
static const size_t UNICODE_UTF16_CODE_UNITS_PADDING = 10;
52
54
 
 
55
 
53
56
/*
54
57
 *-----------------------------------------------------------------------------
55
58
 *
62
65
 *      Otherwise, buffer must be of the specified length, but does
63
66
 *      not need to be NUL-terminated.
64
67
 *
65
 
 *      Note that regardless of the encoding of the buffer passed to this
66
 
 *      function, the returned string can hold any Unicode characters.
67
 
 *
68
 
 *      If the buffer contains an invalid sequence of the specified
69
 
 *      encoding or memory could not be allocated, returns NULL.
 
68
 *      Return NULL on memory allocation failure.
 
69
 *
 
70
 *      Return NULL if strict is true and the buffer contains an invalid
 
71
 *      sequence in the specified encoding.
 
72
 *
 
73
 *      If strict is false, then an invalid sequence is replaced by
 
74
 *      a substitution character, which is either the Unicode
 
75
 *      substitution character (U+FFFD or \xef\xbf\xbd in UTF-8)
 
76
 *      or subchar1 (ASCII SUB or control-z, value 0x1a).
70
77
 *
71
78
 * Results:
72
79
 *      An allocated Unicode string containing the decoded characters
82
89
Unicode
83
90
UnicodeAllocInternal(const void *buffer,      // IN
84
91
                     ssize_t lengthInBytes,   // IN
85
 
                     StringEncoding encoding) // IN
 
92
                     StringEncoding encoding, // IN
 
93
                     Bool strict)             // IN
86
94
{
87
95
   char *utf8Result = NULL;
88
96
 
89
97
   ASSERT(buffer != NULL);
 
98
   ASSERT(lengthInBytes >= 0);
 
99
   ASSERT(Unicode_IsEncodingValid(encoding));
90
100
 
91
 
   encoding = Unicode_ResolveEncoding(encoding);
 
101
   if (!strict) {
 
102
      CodeSet_GenericToGeneric(Unicode_EncodingEnumToName(encoding),
 
103
                               buffer, lengthInBytes,
 
104
                               "UTF-8", CSGTG_TRANSLIT, &utf8Result, NULL);
 
105
      return utf8Result;
 
106
   }
92
107
 
93
108
   switch (encoding) {
94
109
   case STRING_ENCODING_US_ASCII:
95
 
      /*
96
 
       * Fall through and treat as a special case of UTF-8.
97
 
       * Unicode_AllocWithLength() has already ensured we've gotten
98
 
       * only 7-bit bytes in 'buffer'.
99
 
       */
100
110
   case STRING_ENCODING_UTF8:
101
 
      {
102
 
         char *utf16Str;
103
 
         const char *utf8Str = (const char *)buffer;
104
 
 
105
 
         if (lengthInBytes == -1) {
106
 
            lengthInBytes = strlen(utf8Str);
107
 
         }
108
 
 
109
 
         // Ensure the input is valid UTF-8.
110
 
         if (CodeSet_Utf8ToUtf16le(utf8Str,
111
 
                                   lengthInBytes,
112
 
                                   &utf16Str,
113
 
                                   NULL)) {
114
 
            free(utf16Str);
115
 
            utf8Result = Util_SafeStrndup(utf8Str, lengthInBytes);
116
 
         }
117
 
         break;
 
111
      if (Unicode_IsBufferValid(buffer, lengthInBytes, encoding)) {
 
112
         utf8Result = Util_SafeStrndup(buffer, lengthInBytes);
118
113
      }
119
 
   case STRING_ENCODING_UTF16:
 
114
      break;
120
115
   case STRING_ENCODING_UTF16_LE:
121
 
      if (lengthInBytes == -1) {
122
 
         lengthInBytes = Unicode_UTF16Strlen((const utf16_t *)buffer) * 2;
123
 
      }
124
 
 
125
116
      // utf8Result will be left NULL on failure.
126
117
      CodeSet_Utf16leToUtf8((const char *)buffer,
127
118
                            lengthInBytes,
129
120
                            NULL);
130
121
      break;
131
122
   default:
132
 
      if (lengthInBytes == -1) {
133
 
         /*
134
 
          * TODO: This doesn't work for UTF-16 BE, UTF-32, and other
135
 
          * encodings with embedded NULs.
136
 
          */
137
 
         lengthInBytes = strlen((const char *)buffer);
138
 
      }
139
123
      CodeSet_GenericToGeneric(Unicode_EncodingEnumToName(encoding),
140
124
                               buffer, lengthInBytes,
141
 
                               "UTF-8", CSGTG_NORMAL, &utf8Result, NULL);
 
125
                               "UTF-8", 0, &utf8Result, NULL);
142
126
      break;
143
127
   }
144
128
 
149
133
/*
150
134
 *-----------------------------------------------------------------------------
151
135
 *
 
136
 * Unicode_IsBufferValid --
 
137
 *
 
138
 *      Tests if the given buffer is valid in the specified encoding.
 
139
 *
 
140
 *      If lengthInBytes is -1, then buffer must be NUL-terminated.
 
141
 *      Otherwise, buffer must be of the specified length, but does
 
142
 *      not need to be NUL-terminated.
 
143
 *
 
144
 * Results:
 
145
 *      TRUE if the buffer is valid, FALSE if it's not.
 
146
 *
 
147
 * Side effects:
 
148
 *      None
 
149
 *
 
150
 *-----------------------------------------------------------------------------
 
151
 */
 
152
 
 
153
Bool
 
154
Unicode_IsBufferValid(const void *buffer,      // IN
 
155
                      ssize_t lengthInBytes,   // IN
 
156
                      StringEncoding encoding) // IN
 
157
{
 
158
   if (buffer == NULL) {
 
159
      ASSERT(lengthInBytes <= 0);
 
160
      return TRUE;
 
161
   }
 
162
 
 
163
   encoding = Unicode_ResolveEncoding(encoding);
 
164
 
 
165
   if (encoding == STRING_ENCODING_US_ASCII) {
 
166
      return UnicodeSanityCheck(buffer, lengthInBytes, encoding);
 
167
   }
 
168
 
 
169
   if (lengthInBytes == -1) {
 
170
      lengthInBytes = Unicode_LengthInBytes(buffer, encoding);
 
171
   }
 
172
 
 
173
   return CodeSet_Validate(buffer, lengthInBytes,
 
174
                           Unicode_EncodingEnumToName(encoding));
 
175
}
 
176
 
 
177
 
 
178
/*
 
179
 *-----------------------------------------------------------------------------
 
180
 *
152
181
 * Unicode_Duplicate --
153
182
 *
154
183
 *      Allocates and returns a copy of the passed-in Unicode string.
436
465
      // TODO: Lots more encodings can be added here.
437
466
      basicCodePointSize = supplementaryCodePointSize = 1;
438
467
      break;
439
 
   case STRING_ENCODING_UTF16:
440
468
   case STRING_ENCODING_UTF16_LE:
441
469
   case STRING_ENCODING_UTF16_BE:
 
470
   case STRING_ENCODING_UTF16_XE:
442
471
      basicCodePointSize = 2;
443
472
      supplementaryCodePointSize = 4;
444
473
      break;
445
 
   case STRING_ENCODING_UTF32:
446
474
   case STRING_ENCODING_UTF32_LE:
447
475
   case STRING_ENCODING_UTF32_BE:
 
476
   case STRING_ENCODING_UTF32_XE:
448
477
      basicCodePointSize = 4;
449
478
      supplementaryCodePointSize = 4;
450
479
      break;
566
595
         ((char*)destBuffer)[copyBytes] = '\0';
567
596
      }
568
597
      break;
569
 
   case STRING_ENCODING_UTF16:
570
598
   case STRING_ENCODING_UTF16_LE:
571
599
      {
572
600
         char *utf16Buf;
664
692
      return NULL;
665
693
   }
666
694
 
667
 
   return UnicodeGetAllocBytesInternal(str, encoding, NULL);
 
695
   return UnicodeGetAllocBytesInternal(str, encoding, -1, NULL);
 
696
}
 
697
 
 
698
 
 
699
/*
 
700
 *-----------------------------------------------------------------------------
 
701
 *
 
702
 * Unicode_GetAllocBytesWithLength --
 
703
 *
 
704
 *      Allocates and returns a buffer into which the contents of the unicode
 
705
 *      string of the specified length are extracted using the specified
 
706
 *      encoding.
 
707
 *
 
708
 *      NOTE: The buffer returned is always NUL terminated.  The length of
 
709
 *            the NUL can depend on the encoding.  UTF-16 NUL is "\0\0";
 
710
 *            UTF-32 NUL is "\0\0\0\0".
 
711
 *
 
712
 *      NULL is returned for NULL argument.
 
713
 *
 
714
 * Results:
 
715
 *      NULL if argument is NULL.
 
716
 *      Otherwise, pointer to the dynamically allocated memory
 
717
 *      or NULL on conversion failure.
 
718
 *      The caller is responsible to free the memory allocated
 
719
 *      by this routine.
 
720
 *
 
721
 * Side effects:
 
722
 *      None
 
723
 *
 
724
 *-----------------------------------------------------------------------------
 
725
 */
 
726
 
 
727
void *
 
728
Unicode_GetAllocBytesWithLength(ConstUnicode str,        // IN:
 
729
                                StringEncoding encoding, // IN:
 
730
                                ssize_t lengthInBytes)   // IN:
 
731
{
 
732
   if (str == NULL) {
 
733
      return NULL;
 
734
   }
 
735
   ASSERT(lengthInBytes >= 0);
 
736
 
 
737
   return UnicodeGetAllocBytesInternal(str, encoding, lengthInBytes, NULL);
668
738
}
669
739
 
670
740
 
692
762
void *
693
763
UnicodeGetAllocBytesInternal(ConstUnicode ustr,       // IN
694
764
                             StringEncoding encoding, // IN
 
765
                             ssize_t lengthInBytes,   // IN
695
766
                             size_t *retLength)       // OUT: optional
696
767
{
697
768
   const char *utf8Str = ustr;
698
 
   size_t len;
699
769
   char *result = NULL;
700
770
 
701
771
   ASSERT(ustr != NULL);
702
772
 
703
773
   encoding = Unicode_ResolveEncoding(encoding);
704
774
 
705
 
   len = strlen(utf8Str);
 
775
   if (lengthInBytes == -1) {
 
776
      lengthInBytes = Unicode_LengthInBytes(ustr, STRING_ENCODING_UTF8);
 
777
   }
706
778
 
707
779
   switch (encoding) {
708
780
   case STRING_ENCODING_US_ASCII:
709
 
      if (!UnicodeSanityCheck(utf8Str, len, encoding)) {
 
781
      if (!UnicodeSanityCheck(utf8Str, lengthInBytes, encoding)) {
710
782
         break;
711
783
      }
712
784
      // fall through
713
785
   case STRING_ENCODING_UTF8:
714
 
      result = Util_SafeMalloc(len + 1);
715
 
      memcpy(result, utf8Str, len + 1);
 
786
      result = Util_SafeMalloc(lengthInBytes + 1);
 
787
      memcpy(result, utf8Str, lengthInBytes + 1);
716
788
      if (retLength != NULL) {
717
 
         *retLength = len;
 
789
         *retLength = lengthInBytes;
718
790
      }
719
791
      break;
720
792
 
721
 
   case STRING_ENCODING_UTF16:
722
793
   case STRING_ENCODING_UTF16_LE:
723
 
      if (!CodeSet_Utf8ToUtf16le(utf8Str, len, &result, retLength)) {
 
794
      if (!CodeSet_Utf8ToUtf16le(utf8Str, lengthInBytes, &result, retLength)) {
724
795
         // input should be valid UTF-8, no conversion error possible
725
796
         ASSERT_MEM_ALLOC(FALSE);
726
797
      }
727
798
      break;
728
799
 
729
800
   default:
730
 
      if (!CodeSet_GenericToGeneric("UTF-8", utf8Str, len,
 
801
      if (!CodeSet_GenericToGeneric("UTF-8", utf8Str, lengthInBytes,
731
802
                                    Unicode_EncodingEnumToName(encoding),
732
803
                                    CSGTG_NORMAL,
733
804
                                    &result, retLength)) {