diff options
Diffstat (limited to 'lib/striconveha.c')
-rw-r--r-- | lib/striconveha.c | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/lib/striconveha.c b/lib/striconveha.c index 66bff721..08008d8b 100644 --- a/lib/striconveha.c +++ b/lib/striconveha.c @@ -1,5 +1,5 @@ /* Character set conversion with error handling and autodetection. - Copyright (C) 2002, 2005, 2007, 2009-2022 Free Software Foundation, Inc. + Copyright (C) 2002, 2005, 2007, 2009-2024 Free Software Foundation, Inc. Written by Bruno Haible. This file is free software: you can redistribute it and/or modify @@ -88,10 +88,6 @@ uniconv_register_autodetect (const char *name, size_t listlen; size_t memneed; size_t i; - char *memory; - struct autodetect_alias *new_alias; - char *new_name; - const char **new_try_in_order; /* The TRY_IN_ORDER list must not be empty. */ if (try_in_order[0] == NULL) @@ -108,25 +104,24 @@ uniconv_register_autodetect (const char *name, memneed += sizeof (char *) + strlen (try_in_order[i]) + 1; listlen = i; - memory = (char *) malloc (memneed); + void *memory = malloc (memneed); if (memory != NULL) { - new_alias = (struct autodetect_alias *) memory; - memory += sizeof (struct autodetect_alias); + struct autodetect_alias *new_alias = memory; + memory = new_alias + 1; - new_try_in_order = (const char **) memory; - memory += (listlen + 1) * sizeof (char *); + char const **new_try_in_order = memory; + memory = new_try_in_order + listlen + 1; - new_name = (char *) memory; - memcpy (new_name, name, namelen); - memory += namelen; + char *new_name = memcpy (memory, name, namelen); + memory = new_name + namelen; for (i = 0; i < listlen; i++) { size_t len = strlen (try_in_order[i]) + 1; - memcpy (memory, try_in_order[i], len); - new_try_in_order[i] = (const char *) memory; - memory += len; + char *copy = memcpy (memory, try_in_order[i], len); + new_try_in_order[i] = copy; + memory = copy + len; } new_try_in_order[i] = NULL; @@ -224,16 +219,22 @@ mem_iconveha (const char *src, size_t srclen, return 0; } - /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, - we want to use transliteration. */ + /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5 or Citrus/FreeBSD/macOS + iconv, we want to use transliteration. */ #if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \ && !defined __UCLIBC__) \ - || _LIBICONV_VERSION >= 0x0105 + || _LIBICONV_VERSION >= 0x0105 \ + || defined ICONV_SET_TRANSLITERATE if (transliterate) { int retval; size_t len = strlen (to_codeset); char *to_codeset_suffixed = (char *) malloca (len + 10 + 1); + if (to_codeset_suffixed == NULL) + { + errno = ENOMEM; + return -1; + } memcpy (to_codeset_suffixed, to_codeset, len); memcpy (to_codeset_suffixed + len, "//TRANSLIT", 10 + 1); @@ -326,16 +327,22 @@ str_iconveha (const char *src, return result; } - /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5, - we want to use transliteration. */ + /* When using GNU libc >= 2.2 or GNU libiconv >= 1.5 or Citrus/FreeBSD/macOS + iconv, we want to use transliteration. */ #if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \ && !defined __UCLIBC__) \ - || _LIBICONV_VERSION >= 0x0105 + || _LIBICONV_VERSION >= 0x0105 \ + || defined ICONV_SET_TRANSLITERATE if (transliterate) { char *result; size_t len = strlen (to_codeset); char *to_codeset_suffixed = (char *) malloca (len + 10 + 1); + if (to_codeset_suffixed == NULL) + { + errno = ENOMEM; + return NULL; + } memcpy (to_codeset_suffixed, to_codeset, len); memcpy (to_codeset_suffixed + len, "//TRANSLIT", 10 + 1); |