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);  | 
