Пример #1
0
char *
Unicode_ToTitle(const char *str,    // IN
                const char *locale) // IN
{
   UCaseMap *caseMap;
   UErrorCode status = U_ZERO_ERROR;
   char *utf8Dest;
   const char *utf8Src = (const char *)str;
   int32_t utf8SrcLen = strlen(utf8Src);
   int32_t destCapacity = utf8SrcLen + 1;
   int32_t destLen;
   char *result = NULL;

   // Most title-case operations don't change the length of the string.
   utf8Dest = (char *)Util_SafeMalloc(destCapacity);

   caseMap = ucasemap_open(locale, 0, &status);
   if (U_FAILURE(status)) {
      goto out;
   }

   destLen = ucasemap_utf8ToTitle(caseMap,
                                  utf8Dest,
                                  destCapacity,
                                  utf8Src,
                                  utf8SrcLen,
                                  &status);

   if (status != U_BUFFER_OVERFLOW_ERROR) {
      goto out;
   }

   // If we need a bigger buffer, then reallocate and retry.
   destCapacity = destLen + 1;
   utf8Dest = (char *)Util_SafeRealloc(utf8Dest, destCapacity);

   status = U_ZERO_ERROR;
   destLen = ucasemap_utf8ToTitle(caseMap,
                                  utf8Dest,
                                  destCapacity,
                                  utf8Src,
                                  utf8SrcLen,
                                  &status);

  out:
   ucasemap_close(caseMap);

   if (U_SUCCESS(status) && status != U_STRING_NOT_TERMINATED_WARNING) {
      result = utf8Dest;
   } else {
      ASSERT(U_SUCCESS(status));
      ASSERT(status != U_STRING_NOT_TERMINATED_WARNING);
   }

   return result;
}
Пример #2
0
void
StrUtil_SafeStrcat(char **prefix,    // IN/OUT
                   const char *str)  // IN
{
    char *tmp;
    size_t plen = *prefix != NULL ? strlen(*prefix) : 0;
    size_t slen = strlen(str);

    /* Check for overflow */
    VERIFY((size_t)-1 - plen > slen + 1);

    tmp = Util_SafeRealloc(*prefix, plen + slen + 1 /* NUL */);

    memcpy(tmp + plen, str, slen + 1 /* NUL */);
    *prefix = tmp;
}
Пример #3
0
void
StrUtil_SafeStrcat(char **prefix,    // IN/OUT:
                   const char *str)  // IN:
{
   char *tmp;
   size_t plen = (*prefix == NULL) ? 0 : strlen(*prefix);
   size_t slen = strlen(str);

   /*
    * If we're manipulating strings that are anywhere near max(size_t)/2 in
    * length we're doing something very wrong. Avoid potential overflow by
    * checking for "insane" operations. Prevent the problem before it gets
    * started.
    */

   VERIFY((plen < (SIZE_MAX/2)) && (slen < (SIZE_MAX/2)));

   tmp = Util_SafeRealloc(*prefix, plen + slen + 1 /* NUL */);

   memcpy(tmp + plen, str, slen + 1 /* NUL */);
   *prefix = tmp;
}
Пример #4
0
char *
Unicode_ToLower(const char *str,    // IN
                const char *locale) // IN
{
   UCaseMap *caseMap;
   UErrorCode status = U_ZERO_ERROR;
   char *utf8Dest;
   const char *utf8Src = (const char *)str;
   int32_t utf8SrcLen = strlen(utf8Src);
   int32_t destCapacity = utf8SrcLen + 1;
   int32_t destLen;
   char *result = NULL;

   /*
    * XXX TODO: This and the two following functions are substantially
    * identical.  Refactor them!  (Note that ucasemap_utf8ToTitle
    * takes a non-const UCaseMap, so we can't just use pointers to
    * functions unless we cast.)
    */

   // Most lower-case operations don't change the length of the string.
   utf8Dest = (char *)Util_SafeMalloc(destCapacity);

   caseMap = ucasemap_open(locale, 0, &status);
   if (U_FAILURE(status)) {
      goto out;
   }

   destLen = ucasemap_utf8ToLower(caseMap,
                                  utf8Dest,
                                  destCapacity,
                                  utf8Src,
                                  utf8SrcLen,
                                  &status);

   if (status != U_BUFFER_OVERFLOW_ERROR) {
      goto out;
   }

   // If we need a bigger buffer, then reallocate and retry.
   destCapacity = destLen + 1;
   utf8Dest = (char *)Util_SafeRealloc(utf8Dest, destCapacity);

   status = U_ZERO_ERROR;
   destLen = ucasemap_utf8ToLower(caseMap,
                                  utf8Dest,
                                  destCapacity,
                                  utf8Src,
                                  utf8SrcLen,
                                  &status);

  out:
   ucasemap_close(caseMap);

   if (U_SUCCESS(status) && status != U_STRING_NOT_TERMINATED_WARNING) {
      result = utf8Dest;
   } else {
      ASSERT(U_SUCCESS(status));
      ASSERT(status != U_STRING_NOT_TERMINATED_WARNING);
   }

   return result;
}
LONG
Win32U_AllocRegQueryValueEx(HKEY keyName,      // IN:
                            LPCSTR valueName,  // IN: can be NULL
                            LPDWORD reserved,  // IN: reserved
                            LPDWORD type,      // OUT/OPT: can be NULL
                            LPBYTE *data,      // OUT:
                            LPDWORD dataSize)  // OUT:
{
   LONG ret;
   utf16_t *valueNameW = Unicode_GetAllocUTF16(valueName);
   DWORD valueType;
   char *rawData = NULL;
   DWORD rawDataSize = 0;
   DWORD bufferSize = 0;

   ASSERT(data);
   ASSERT(dataSize);
   ASSERT(reserved == NULL);

   *data = NULL;
   *dataSize = 0;

   ret = RegQueryValueExW(keyName, valueNameW, reserved, NULL, NULL,
                          &bufferSize);
   if (ret != ERROR_SUCCESS || bufferSize == 0) {
      bufferSize = 256;
   }

   /*
    * This loops with a growing buffer because:
    * * The registry value could be modified between calls to
    *   RegQueryValueExW.
    * * RegQueryValueExW will never tell us how large a buffer we need
    *   for HKEY_PERFORMANCE_DATA values.
    */

   while (TRUE) {
      rawData = Util_SafeRealloc(rawData, bufferSize);
      rawDataSize = bufferSize;
      ret = RegQueryValueExW(keyName, valueNameW, reserved, &valueType,
                             rawData, &rawDataSize);
      if (ERROR_MORE_DATA != ret) {
         break;
      }
      bufferSize *= 2;
   }

   if (ERROR_SUCCESS != ret) {
      goto exit;
   }

   ASSERT(rawDataSize <= bufferSize);

   /* Write back the data */
   switch (valueType) {
      /* Do UTF-16->UTF-8 conversion for string types. */
      case REG_SZ:
      case REG_MULTI_SZ:
      case REG_EXPAND_SZ:
      {
         size_t sizeOut;

         if (!CodeSet_Utf16leToUtf8(rawData, rawDataSize, data, &sizeOut)) {
            /*
             * Someone may not have set the right data size.  Let's try
             * to convert up to NUL if one is found.
             */

            DWORD lenInBytes = rawDataSize;
            const utf16_t *p1 = (utf16_t*)rawData;
            const utf16_t *p2 = (utf16_t*)&rawData[rawDataSize];
            
            if (valueType == REG_MULTI_SZ) {    /* look for four NUL bytes */
               while (p1 < p2) {
                  for (; *p1 != 0 && p1 < p2; p1++) {
                  }
                  p1++;
                  if (p1 < p2 && *p1 == 0) {
                     lenInBytes = (char *)p1 - rawData + 2;
                     break;
                  }
               }
            } else {
               for (; *p1 != 0 && p1 < p2; p1++) {
               }
               if (p1 < p2) {
                  lenInBytes = (char *)p1 - rawData + 2;
               }
            }

            ASSERT(lenInBytes <= rawDataSize);
            ASSERT(lenInBytes % 2 == 0);

            if (lenInBytes >= rawDataSize ||
                !CodeSet_Utf16leToUtf8(rawData, lenInBytes, data, &sizeOut)) {
               ret = ERROR_INVALID_DATA;
               goto exit;
            }
         }
         *dataSize = sizeOut;
         break;
      }
      default:
         /* Shrink the buffer down to what we actually used. */
         *data = Util_SafeRealloc(rawData, rawDataSize);
         *dataSize = rawDataSize;
         rawData = NULL;
         break;
   }

   /* Write back the type information if asked for */
   if (type) {
      *type = valueType;
   }

exit:
   free(valueNameW);
   free(rawData);

   return ret;
}