From patchwork Tue Jun 20 19:12:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 106013 Delivered-To: patch@linaro.org Received: by 10.140.91.2 with SMTP id y2csp1556804qgd; Tue, 20 Jun 2017 12:12:41 -0700 (PDT) X-Received: by 10.99.165.17 with SMTP id n17mr31577887pgf.163.1497985961810; Tue, 20 Jun 2017 12:12:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497985961; cv=none; d=google.com; s=arc-20160816; b=ahN90JldjZFyGzkGgIcz7A7rmpArFwxN7MKL9WDllXz/CFhwzd3LQgOb7jG73dww4w Db7Wm8sfBSWDtdoV5TlLExxOi9s80JG25dH4KuShMZVyWd8/pEWC+F7lQ7HNXngEvT/t 6Vtd+zaiur4FSugXBrfqxhj1X7Eqv21hcuv/RHkyymofh0EBadp+0/3hWvTGG3n94mIC 7J4prR0XIY6x4Diww7NiyW2eHilWL6BM5o/wAoCOb7IqmULSILbljccVU1GveZ3GmEf3 R9SuRonHOzJ7zv2H2cc4tLAOlUKQ0x/Q+Nai/SfWyO2RK1hXVvxW3A6CRt1d34jHp6Qs B5kA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:cc:to:from:delivered-to:sender:list-help :list-post:list-archive:list-subscribe:list-unsubscribe:list-id :precedence:mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=IOwtsQLC9/RR76AIMdgwaIVlnS1J4KS+RF5HU8RA+bs=; b=0/0M1YMXtLq0XUbGljhdrPE+9rlgAOUYWFYL2rphk7AaEyfxPJrxFwfVNuQ3hDyKq+ Cm1GgIAkfH9EX7P8aCHkDfK3NSSj9RVUAObPbBvGicCtjXbmZJkr2AqhJJKT7w3kaTLr Smw9oiIliGGI6VsUnCc0Uvv2saVS1Btmy5Tw346CAwerDZCjlP69sKCqvvokytJI+IIM soUjxI882l/3FyJl6Mjs9v41CMAQGucWg0KNgZsOY/y/F+m289MHObfHdSB093e0jex1 lgUuCdm983eBHXDqJjRQ6n3TSZ9LmLeDenksqB1GP1ku1J+r1/nIgoOEWeLM9za4d5tu shDQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.b=ninPSzfo; spf=pass (google.com: domain of libc-alpha-return-80842-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-80842-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id a6si11130350pfb.310.2017.06.20.12.12.41 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 20 Jun 2017 12:12:41 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-80842-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.b=ninPSzfo; spf=pass (google.com: domain of libc-alpha-return-80842-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-80842-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id; q=dns; s= default; b=HR03oNBvM0mCyN7mClYblsDQDPh4d+EECH7+5j2NP9NuGTmP7fjDB d/L5ScwHDncmrFhQ9S5c4nMBHWJmVWLgAAl6EnsgulDL2wUpo1d/VLmufbdRME0W Kvjj2l45l4/GFC3Uf4LWs/Z8mOC9ZjqmFzSQ1HcGUG409wtF1himXw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id; s=default; bh=Xx2wl8xiG2GX06+2Qc9lVAEwyHQ=; b=ninPSzfo+igCL2hRtv2CCUW5HGtj BgFF6K9LMOlzSkj8Ofp4TEyhTichjk8n/Wb/DBiMa76QMzb22c9qMlH31vlVlQp4 e7TCVBgpTRurtQWUbv/H8BZj1fF/eoXE+YaBUKuaFiHKfxJbQ1vDIL+IuyluQduz woA5gD7ZPYWzWmQ= Received: (qmail 124041 invoked by alias); 20 Jun 2017 19:12:16 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 123904 invoked by uid 89); 20 Jun 2017 19:12:15 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-ua0-f177.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=IOwtsQLC9/RR76AIMdgwaIVlnS1J4KS+RF5HU8RA+bs=; b=No04VRBFUUGIyMysxZL5vLCifqV/urg4y/84QtEtvDWc4/uCl86WFQY1qVcluTB/vu qigCoipMT3gT6B1ZQOh6gl/9Kr0rt0ABZiQaPKbHZVLPlnxsVrxdGQ2vWe9cwmE3RbVU Mg9MwOu4XsV8mPT9HAt3mwLWm3UEPYx8F1K0ZZdvP9LEMjHJs2dzX0leYPQ2H7fIoAbE AO9H+8RwNUWS8tTP9efSn03ccMTxRBqd2IC+YGJx5RwAskLIJ8nvYtPlgy9QnkZhEZlY L3BlVUigLDWhZVL2laFYZRLqiJYxqoySX/MYg82vYxc7JPvSWdUTrLqgT5tfqJQGP2qM huMQ== X-Gm-Message-State: AKS2vOxZ5yX+EM+GWtsQh2DgYXglx3BfipViGGjwvXKIsLV5/Xcg9+cN INTECF6sXpcmUMxM7neVkg== X-Received: by 10.176.17.26 with SMTP id e26mr6476358uab.94.1497985928754; Tue, 20 Jun 2017 12:12:08 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Florian Weimer Subject: [PATCH 1/2] malloc: Add specialized dynarray for C strings Date: Tue, 20 Jun 2017 16:12:02 -0300 Message-Id: <1497985923-18986-1-git-send-email-adhemerval.zanella@linaro.org> This patch adds an specialized dynarray to manage C strings using the dynarray internal implementation. It uses some private fields from dynarray and thus it provided specific files to access and manage the internal string buffer. For instance: struct char_array str; // str == "testing" char_array_init_str (&str, "testing"); // c == 's' char c = char_array_pos (&str, 2); // str = "testing2" char_array_set_str (&str, "testing2"); // str = "testi" char_array_erase (&str, 5); // str = "123testi" char_array_prepend_str (&str, "123"); // len = 8 size_t len = char_array_length (&str); // str = "123testi456" char_array_append_str (&str, "456"); // str = "123testi789" char_array_replace_str_pos (&str, 7, "789", 3); The provided function are not extensive and meant mainly to be use in subsequent glob implementation cleanup. For internal object consistency only the function provided by char_array.c should be used, including internal object manipulation. To check for possible overflows in internal size manipulation a new function, check_add_wrapv_size_t, is added on malloc-internal. It basically return whether the addition of two size_t overflows. Checked on x86_64-linux-gnu. * malloc/Makefile (test-internal): Add tst-char_array. (routines): Add dynarray_overflow_failure and char_array-impl. * malloc/Versions [GLIBC_PRIVATE] (libc): Add __libc_dynarray_overflow_failure, __char_array_set_str_size, __char_array_erase, __char_array_prepend_str_size, and __char_array_replace_str_pos. * malloc/char_array-impl.c: New file. * malloc/char_array-skeleton.c: Likewise. * malloc/char_array.h: Likewise. * malloc/tst-char-array.c: Likewise. * malloc/dynarray_overflow_failure.c: Likewise. * malloc/malloc-internal.h (check_add_overflow_size_t): New function. --- malloc/Makefile | 4 +- malloc/Versions | 7 + malloc/char_array-impl.c | 57 ++++++++ malloc/char_array-skeleton.c | 263 +++++++++++++++++++++++++++++++++++++ malloc/char_array.h | 53 ++++++++ malloc/dynarray.h | 8 ++ malloc/dynarray_overflow_failure.c | 31 +++++ malloc/malloc-internal.h | 14 ++ malloc/tst-char_array.c | 110 ++++++++++++++++ 9 files changed, 546 insertions(+), 1 deletion(-) create mode 100644 malloc/char_array-impl.c create mode 100644 malloc/char_array-skeleton.c create mode 100644 malloc/char_array.h create mode 100644 malloc/dynarray_overflow_failure.c create mode 100644 malloc/tst-char_array.c -- 2.7.4 diff --git a/malloc/Makefile b/malloc/Makefile index 14c13f1..3d81fd1 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -46,6 +46,7 @@ tests-internal += \ tst-dynarray \ tst-dynarray-fail \ tst-dynarray-at-fail \ + tst-char_array ifneq (no,$(have-tunables)) tests += tst-malloc-usable-tunables @@ -58,11 +59,12 @@ test-srcs = tst-mtrace routines = malloc morecore mcheck mtrace obstack reallocarray \ scratch_buffer_grow scratch_buffer_grow_preserve \ scratch_buffer_set_array_size \ - dynarray_at_failure \ + dynarray_at_failure dynarray_overflow_failure \ dynarray_emplace_enlarge \ dynarray_finalize \ dynarray_resize \ dynarray_resize_clear \ + char_array-impl install-lib := libmcheck.a non-lib.a := libmcheck.a diff --git a/malloc/Versions b/malloc/Versions index 5b54306..e49b817 100644 --- a/malloc/Versions +++ b/malloc/Versions @@ -82,9 +82,16 @@ libc { # dynarray support __libc_dynarray_at_failure; + __libc_dynarray_overflow_failure; __libc_dynarray_emplace_enlarge; __libc_dynarray_finalize; __libc_dynarray_resize; __libc_dynarray_resize_clear; + + # char_array support + __char_array_set_str_size; + __char_array_erase; + __char_array_prepend_str_size; + __char_array_replace_str_pos; } } diff --git a/malloc/char_array-impl.c b/malloc/char_array-impl.c new file mode 100644 index 0000000..5a56bbc --- /dev/null +++ b/malloc/char_array-impl.c @@ -0,0 +1,57 @@ +/* Specialized dynarray for C strings. Implementation file. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +void +__char_array_set_str_size (struct dynarray_header *header, const char *str, + size_t size) +{ + *((char *) mempcpy (header->array, str, size)) = '\0'; + header->used = size + 1; +} +libc_hidden_def (__char_array_set_str_size) + +void +__char_array_erase (struct dynarray_header *header, size_t pos) +{ + char *ppos = header->array + pos; + char *lpos = header->array + header->used; + ptrdiff_t size = lpos - ppos; + memmove (ppos, ppos + 1, size); + header->used--; +} +libc_hidden_def (__char_array_erase) + +void +__char_array_prepend_str_size (struct dynarray_header *header, + const char *str, size_t size, size_t used) +{ + memmove (header->array + size, header->array, used); + memcpy (header->array, str, size); +} +libc_hidden_def (__char_array_prepend_str_size) + +void +__char_array_replace_str_pos (struct dynarray_header *header, size_t pos, + const char *str, size_t len) +{ + char *start = header->array + pos; + *(char *) mempcpy (start, str, len) = '\0'; +} +libc_hidden_def (__char_array_replace_str_pos) diff --git a/malloc/char_array-skeleton.c b/malloc/char_array-skeleton.c new file mode 100644 index 0000000..7ad274e --- /dev/null +++ b/malloc/char_array-skeleton.c @@ -0,0 +1,263 @@ +/* Specialized dynarray for C strings. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* This file provides a dynamic C string with an initial stack allocated + buffer. Since it is based on dynarray, it provided dynamic size + expansion and heap usage for large strings. + + The following parameters are optional: + + CHAR_ARRAY_INITIAL_SIZE + The size of the statically allocated array (default is 256). It will + be used to define DYNARRAY_INITIAL_SIZE. + + The following functions are provided: + + bool char_array_init_empty (struct char_array *); + bool char_array_init_str (struct char_array *, const char *); + bool char_array_init_str_size (struct char_array *, const char *, size_t); + bool char_array_is_empty (struct char_array *); + const char *char_array_str (struct char_array *); + char char_array_pos (struct char_array *, size_t); + size_t char_array_length (struct char_array *); + bool char_array_set_str (struct char_array *, const char *); + bool char_array_set_str_size (struct char_array *, const char *, size_t); + void char_array_erase (struct char_array *, size_t); + bool char_array_crop (struct char_array *, size_t); + bool char_array_prepend_str (struct char_array *, const char *); + bool char_array_append_str (struct char_array *, const char *); + bool char_array_replace_str_pos (struct char_array *, size_t, const char *, + size_t); + + For instance: + + struct char_array str; + // str == "testing"; + char_array_init_str (&str, "testing"); + // c == 's' + char c = char_array_pos (&str, 2); + // str = "testing2"; + char_array_set_str (&str, "testing2"); + // str = "testi"; + char_array_erase (&str, 5); + // str = "123testi"; + char_array_prepend_str (&str, "123"); + // len = 8; + size_t len = char_array_length (&str); + // str = "123testi456"; + char_array_append_str (&str, "456"); + // str = "123testi789"; + char_array_replace_str_pos (&str, 7, "789", 3); + */ + +#define DYNARRAY_STRUCT char_array +#define DYNARRAY_ELEMENT char +#define DYNARRAY_PREFIX char_array_ +#ifndef CHAR_ARRAY_INITIAL_SIZE +# define CHAR_ARRAY_INITIAL_SIZE 256 +#endif +#define DYNARRAY_INITIAL_SIZE CHAR_ARRAY_INITIAL_SIZE +#include + +#include +#include + +/* Return a const char for the internal C string handled by 'array'. */ +__attribute__ ((unused, nonnull (1))) +static const char * +char_array_str (struct char_array *array) +{ + return char_array_begin (array); +} + +/* Return the character at position 'pos' from the char_array 'array'. */ +__attribute__ ((unused, nonnull (1))) +static char +char_array_pos (struct char_array *array, size_t pos) +{ + return *char_array_at (array, pos); +} + +/* Calculate the length of the string, excluding the terminating null. */ +__attribute__ ((unused, nonnull (1))) +static size_t +char_array_length (struct char_array *array) +{ + /* Exclude the final '\0'. */ + return array->dynarray_header.used - 1; +} + +/* Copy up 'size' bytes from string 'str' to char_array 'array'. A final + '\0' is appended in the char_array. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_set_str_size (struct char_array *array, const char *str, + size_t size) +{ + size_t newsize; + if (check_add_overflow_size_t (size, 1, &newsize)) + __libc_dynarray_overflow_failure (size, 1); + + if (!char_array_resize (array, newsize)) + return false; + + __char_array_set_str_size (&array->dynarray_abstract, str, size); + return true; +} + +/* Copy the contents of string 'str' to char_array 'array', including the + final '\0'. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_set_str (struct char_array *array, const char *str) +{ + return char_array_set_str_size (array, str, strlen (str)); +} + +/* Initialize the char_array 'array' and sets it to an empty string (""). */ +__attribute__ ((unused, nonnull (1))) +static bool +char_array_init_empty (struct char_array *array) +{ + char_array_init (array); + return char_array_set_str (array, ""); +} + +/* Initialize the char_array 'array' and copy the content of string 'str'. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_init_str (struct char_array *array, const char *str) +{ + char_array_init (array); + return char_array_set_str (array, str); +} + +/* Initialize the char_array 'array' and copy the content of string 'str' + up to 'size' characteres. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_init_str_size (struct char_array *array, const char *str, + size_t size) +{ + char_array_init (array); + return char_array_set_str_size (array, str, size); +} + +/* Return if the char_array contain any characteres. */ +__attribute__ ((unused, nonnull (1))) +static bool +char_array_is_empty (struct char_array *array) +{ + return *char_array_begin (array) == '\0'; +} + +/* Remove the byte at position 'pos' from char_array 'array'. The contents + are moved internally if the position is not at the end of the internal + buffer. */ +__attribute__ ((unused, nonnull (1))) +static bool +char_array_erase (struct char_array *array, size_t pos) +{ + if (pos >= array->dynarray_header.used - 1) + return false; + + __char_array_erase (&array->dynarray_abstract, pos); + return true; +} + +/* Resize the char_array 'array' to size 'count' maintaining the ending + '\0' byte. */ +__attribute__ ((unused, nonnull (1))) +static bool +char_array_crop (struct char_array *array, size_t size) +{ + if (size >= (array->dynarray_header.used - 1) + || !char_array_resize (array, size + 1)) + return false; + + array->dynarray_header.array[size] = '\0'; + return true; +} + +/* Prepend the contents of string 'str' to char_array 'array', including the + final '\0' byte. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_prepend_str (struct char_array *array, const char *str) +{ + size_t size = strlen (str); + /* Resizing the array might change its used elements and we need below + to correct copy the elements. */ + size_t used = array->dynarray_header.used; + + size_t newsize; + if (check_add_overflow_size_t (used, size, &newsize)) + __libc_dynarray_overflow_failure (used, size); + + /* Make room for the string and copy it. */ + if (!char_array_resize (array, newsize)) + return false; + __char_array_prepend_str_size (&array->dynarray_abstract, str, size, used); + return true; +} + +/* Append the contents of string 'str' to char_array 'array, including the + final '\0' byte. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_append_str (struct char_array *array, const char *str) +{ + size_t size = strlen (str); + /* Resizing the array might change its used elements and it used it below + to correct copy the elements. */ + size_t used = array->dynarray_header.used - 1; + + /* 'used' does account for final '\0', so there is no need to add + an extra element to calculate the final required size. */ + size_t newsize; + if (check_add_overflow_size_t (used + 1, size, &newsize)) + __libc_dynarray_overflow_failure (used + 1, size); + + if (!char_array_resize (array, newsize)) + return false; + + /* Start to append at '\0' up to string length and add a final '\0'. */ + *(char*) mempcpy (array->dynarray_header.array + used, str, size) = '\0'; + return true; +} + +/* Replace the contents starting of position 'pos' of char_array 'array' + with the contents of string 'str' up to 'len' bytes. A final '\0' + is appended in the string. */ +__attribute__ ((unused, nonnull (1, 3))) +static bool +char_array_replace_str_pos (struct char_array *array, size_t pos, + const char *str, size_t len) +{ + if (pos > array->dynarray_header.used) + __libc_dynarray_at_failure (array->dynarray_header.used, pos); + + size_t newsize; + if (check_add_overflow_size_t (pos, len, &newsize) + || check_add_overflow_size_t (newsize, 1, &newsize) + || !char_array_resize (array, newsize)) + return false; + + __char_array_replace_str_pos (&array->dynarray_abstract, pos, str, len); + return true; +} diff --git a/malloc/char_array.h b/malloc/char_array.h new file mode 100644 index 0000000..c696673 --- /dev/null +++ b/malloc/char_array.h @@ -0,0 +1,53 @@ +/* Specialized dynarray for C strings. Shared definitions. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _CHAR_ARRAY_H +#define _CHAR_ARRAY_H + +#include + +/* Internal funciton. Set the dynarray to the content of the string STR up + to SIZE bytes. The dynarray must be resized previously. */ +void __char_array_set_str_size (struct dynarray_header *, const char *str, + size_t size); + +/* Internal function. Remove the character at position POS from dynarray. + The position must be a valid one. */ +void __char_array_erase (struct dynarray_header *, size_t pos); + +/* Internal function. Prepend the content of string STR up to SIZE bytes to + dynarray by moving USED bytes forward. The dynarray must be resized + previously. */ +void __char_array_prepend_str_size (struct dynarray_header *, + const char *str, size_t size, + size_t used); + +/* Internal function. Replace the content of dynarray starting at position + POS with the content of string STR up to LEN bytes. The dynarray must + be resize previously and STR must contain at least LEN bytes. */ +void __char_array_replace_str_pos (struct dynarray_header *, size_t pos, + const char *str, size_t len); + +#ifndef _ISOMAC +libc_hidden_proto (__char_array_set_str_size) +libc_hidden_proto (__char_array_erase) +libc_hidden_proto (__char_array_prepend_str_size) +libc_hidden_proto (__char_array_replace_str_pos) +#endif + +#endif diff --git a/malloc/dynarray.h b/malloc/dynarray.h index 5888bcb..773c080 100644 --- a/malloc/dynarray.h +++ b/malloc/dynarray.h @@ -176,4 +176,12 @@ libc_hidden_proto (__libc_dynarray_finalize) libc_hidden_proto (__libc_dynarray_at_failure) #endif +/* Internal function. TErminate the process after an overflow in + new size allocation. SIZE is the current number of elements in + dynamic array and INCR is the new elements to add on current + size. */ +void __libc_dynarray_overflow_failure (size_t size, size_t incr) + __attribute__ ((noreturn)); +libc_hidden_proto (__libc_dynarray_overflow_failure) + #endif /* _DYNARRAY_H */ diff --git a/malloc/dynarray_overflow_failure.c b/malloc/dynarray_overflow_failure.c new file mode 100644 index 0000000..14936b0 --- /dev/null +++ b/malloc/dynarray_overflow_failure.c @@ -0,0 +1,31 @@ +/* Report an dynamic array size overflow condition. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +void +__libc_dynarray_overflow_failure (size_t size, size_t incr) +{ + char buf[200]; + __snprintf (buf, sizeof (buf), "Fatal glibc error: " + "new size overflows (old %zu and increment %zu)\n", + size, incr); + __libc_fatal (buf); +} +libc_hidden_def (__libc_dynarray_overflow_failure) diff --git a/malloc/malloc-internal.h b/malloc/malloc-internal.h index dbd801a..8f3e6e7 100644 --- a/malloc/malloc-internal.h +++ b/malloc/malloc-internal.h @@ -101,4 +101,18 @@ check_mul_overflow_size_t (size_t left, size_t right, size_t *result) #endif } +/* Set *R = A + B. Return true if the answer is mathematically incorrect due + to overflow; in this case, *R is the low order bits of the correct + answer. */ +static inline bool +check_add_overflow_size_t (size_t a, size_t b, size_t *r) +{ +#if 5 <= __GNUC__ + return __builtin_add_overflow (a, b, r); +#else + *r = a + b; + return *r < a; +#endif +} + #endif /* _MALLOC_INTERNAL_H */ diff --git a/malloc/tst-char_array.c b/malloc/tst-char_array.c new file mode 100644 index 0000000..f55acb9 --- /dev/null +++ b/malloc/tst-char_array.c @@ -0,0 +1,110 @@ +/* Test for char_array. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#include + +#include +#include +#include +#include +#include + +static int +do_test (void) +{ + mtrace (); + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_empty (&str) == true); + TEST_VERIFY_EXIT (char_array_length (&str) == 0); + TEST_VERIFY_EXIT (char_array_is_empty (&str) == true); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "") == 0); + char_array_free (&str); + } + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_str (&str, "testing")); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("testing")); + TEST_VERIFY_EXIT (char_array_pos (&str, 2) == 's'); + TEST_VERIFY_EXIT (char_array_is_empty (&str) == false); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "testing") == 0); + char_array_free (&str); + } + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_str_size (&str, "testing", 4)); + TEST_VERIFY_EXIT (char_array_length (&str) == 4); + TEST_VERIFY_EXIT (char_array_pos (&str, 2) == 's'); + TEST_VERIFY_EXIT (char_array_is_empty (&str) == false); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "test") == 0); + char_array_free (&str); + } + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_str (&str, "testing")); + TEST_VERIFY_EXIT (char_array_set_str (&str, "abcdef")); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "abcdef") == 0); + TEST_VERIFY_EXIT (char_array_set_str_size (&str, "abcdef", 4)); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "abcd") == 0); + char_array_free (&str); + } + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_str (&str, "testing")); + TEST_VERIFY_EXIT (char_array_erase (&str, 4) == true); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("testing") - 1); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "testng") == 0); + TEST_VERIFY_EXIT (char_array_erase (&str, char_array_length (&str)) + == false); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("testing") - 1); + TEST_VERIFY_EXIT (char_array_erase (&str, char_array_length (&str) - 1) + == true); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("testing") - 2); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "testn") == 0); + char_array_free (&str); + } + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_str (&str, "test")); + TEST_VERIFY_EXIT (char_array_prepend_str (&str, "123")); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "123test") == 0); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("123test")); + TEST_VERIFY_EXIT (char_array_append_str (&str, "456")); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "123test456") == 0); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("123test456")); + TEST_VERIFY_EXIT (char_array_replace_str_pos (&str, 7, "789", 3)); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "123test789") == 0); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("123test789")); + TEST_VERIFY_EXIT (char_array_crop (&str, 7)); + TEST_VERIFY_EXIT (char_array_length (&str) == 7); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "123test") == 0); + char_array_free (&str); + } + + return 0; +} + +#include From patchwork Tue Jun 20 19:12:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 106012 Delivered-To: patch@linaro.org Received: by 10.140.91.2 with SMTP id y2csp1556664qgd; Tue, 20 Jun 2017 12:12:26 -0700 (PDT) X-Received: by 10.98.19.145 with SMTP id 17mr32075950pft.208.1497985946810; Tue, 20 Jun 2017 12:12:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497985946; cv=none; d=google.com; s=arc-20160816; b=ER/ACsEAFPOwm8RZpUClyGkyeUSuPt+Tpd02803zNdelW70aOW3oO3SnUEMa6cF6jG oWmNNUUTZWy8Yq7I0FYCUmg6OLWxi5FuWnpxgFMi3kJ8c5orVPqwHiNuYrUVrYL34DIj b9D/ZKw+2s+7JcJ2wlgIz3fKb4dh4sDUsZCDyxZ1P9y7nXekSree0ltmhQxDf9TLu5qS bCTiFeY1HLDbtS7T9tdc/Xq6RM9qrGExCvqhIKNGrTUQS5UeMZWy7ve4cPogrg5DYlcj x3TkiRUA1U37ItPW9S4eNAEB/IS5Lgitv0UW4IP9vbHvNWhL2ZkD/JXnirmibwORarrt 3SqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :delivered-to:sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=65P/FxIJnJukAuIZ7gIcVKcdqOy41/sCSJHy6WzUdo8=; b=ziMQIh5AAlqlBE6oy0j8P4ACYeF88KTCI0mWllyP2m4ywTbOSK7pRt9ECbeFDymZRF //Qx6NVsFTWLUVtW13coMbaEH72DfT9bSzG4Ar377/cHoC5LichHoYlArZgfC2klbwBK m36RCWgmeceAb8YOR9vG28LOVsS+1/6ZvWqeOY+BTcpaH5T0sBHyybFi9fjhPqwoBNwK eQ8NGUg2h4jh5RMFJT+kETPrCjE2Doh5JJPGjdtXBeRcKoFa25COPTu4LpEeJnkYRpgq rHXSDeoXoUiopyFIsR3rlV2GW0OsLQicGE0bcaxzQjhX3vDZ6PzjkGKY8dyIzI/Ul0pw SAlw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.b=mV9Wgy8b; spf=pass (google.com: domain of libc-alpha-return-80841-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-80841-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id t64si11286803pgd.567.2017.06.20.12.12.26 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 20 Jun 2017 12:12:26 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-80841-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.b=mV9Wgy8b; spf=pass (google.com: domain of libc-alpha-return-80841-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-80841-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=F+zDUkzAtpxAL85UTYzneTjodgB3iTF olG0JE/qi3sNEtZ1QjSj8syF8fA3cMv4mH1etFf4BmfEtPPWmHVeFUFrLx7XDBwX KSWOfBC9+jKtHhp6kmcz9IglJlsRh1rn2XgL0Ub9fJk11TehWVIUw9KSFYqrjDD3 S1aw47sm9HJ4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references; s=default; bh=FWZbzVNTLJduLUZe8rWbDo+5CyE=; b=mV9Wg y8b7qtJPL8JIn1JAEOovMkmRnHh9TvR9arcHh1P/8edIC2y9oEVJkPHadW8GPoY6 Umjg4X7RQDJQtWOo/99G7DUaVzHFp+w7Kly7xlBt6sYUF8zJZnWx8dBqYPjFmRaS xc+XcGqVe3vpqVEIT+UQu79QVUYaNK9ErISxYU= Received: (qmail 123896 invoked by alias); 20 Jun 2017 19:12:15 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 123878 invoked by uid 89); 20 Jun 2017 19:12:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-ua0-f170.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=65P/FxIJnJukAuIZ7gIcVKcdqOy41/sCSJHy6WzUdo8=; b=e/0QKFQCPoIXU2Cfy/XNzyAXMQ6gENFlOWlEqgfXyCpvi2bcHRtxB185OTJPZipr77 f28gr34xZgtmLWS0apqS+Xes28LkLwdVVhrfsp7LG0v1J0jjMNyElfrh0KKjBjj+HLb1 E3BOT/DCeNYHRXBstol7E6kLOu6nOnTbAA5pR02iaFDluF5hx+Pqni5WiFvlQUdiNVTF xVd2CloiKe0GQUi5wG7Of9IRJI1flbfCcLSLZRvFg3T5PMHzOXrV0EXe5cD6tYRrBS9Q 6HBI1Z2xvpBNp7XrK2A1rZh7NozaXir4j/Mp5HtBZNr7jtXs1XMSvMPDBQ/ur4TW6eC1 Tz/w== X-Gm-Message-State: AKS2vOxx25zdturAEmClhnNG4zqS5J891OdYI281Ha91kXw5Z92l2red U6LnDeKxF0gcT2qZNqVoNw== X-Received: by 10.176.26.5 with SMTP id a5mr6529443uai.96.1497985930185; Tue, 20 Jun 2017 12:12:10 -0700 (PDT) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Florian Weimer Subject: [PATCH 2/2] gconv: Replace norm_add_slashes with __gconv_norm_add_slashes Date: Tue, 20 Jun 2017 16:12:03 -0300 Message-Id: <1497985923-18986-2-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1497985923-18986-1-git-send-email-adhemerval.zanella@linaro.org> References: <1497985923-18986-1-git-send-email-adhemerval.zanella@linaro.org> From: Florian Weimer 2017-06-19 Florian Weimer Adhemerval Zanella * iconv/Makefile (routine): Add norm_add_slashes. * iconv/norm_add_slashes.c: New file, extracted from iconv/gconv_int.h. * iconv/gconv_int.h (norm_add_slashes): Remove. (__gconv_norm_add_slashes): Declare. * wcsmbs/wcsmbsload.c (__wcsmbs_load_conv): Use __gconv_norm_add_slashes. * intl/dcigettext.c (_nl_find_msg): Likewise. Simplify !_LIBC case. --- iconv/Makefile | 3 ++- iconv/gconv_int.h | 39 ++++++-------------------------- iconv/norm_add_slashes.c | 53 +++++++++++++++++++++++++++++++++++++++++++ intl/dcigettext.c | 59 ++++++++++++++++++++++++++---------------------- wcsmbs/wcsmbsload.c | 9 +++++--- 5 files changed, 100 insertions(+), 63 deletions(-) create mode 100644 iconv/norm_add_slashes.c -- 2.7.4 diff --git a/iconv/Makefile b/iconv/Makefile index b2fead0..df82b0d 100644 --- a/iconv/Makefile +++ b/iconv/Makefile @@ -25,7 +25,8 @@ include ../Makeconfig headers = iconv.h gconv.h routines = iconv_open iconv iconv_close \ gconv_open gconv gconv_close gconv_db gconv_conf \ - gconv_builtin gconv_simple gconv_trans gconv_cache + gconv_builtin gconv_simple gconv_trans gconv_cache \ + norm_add_slashes routines += gconv_dl vpath %.c ../locale/programs ../intl diff --git a/iconv/gconv_int.h b/iconv/gconv_int.h index 85a67ad..7a54e0f 100644 --- a/iconv/gconv_int.h +++ b/iconv/gconv_int.h @@ -121,38 +121,13 @@ extern const char *__gconv_path_envvar attribute_hidden; __libc_lock_define (extern, __gconv_lock attribute_hidden) -/* The gconv functions expects the name to be in upper case and complete, - including the trailing slashes if necessary. */ -#define norm_add_slashes(str,suffix) \ - ({ \ - const char *cp = (str); \ - char *result; \ - char *tmp; \ - size_t cnt = 0; \ - const size_t suffix_len = strlen (suffix); \ - \ - while (*cp != '\0') \ - if (*cp++ == '/') \ - ++cnt; \ - \ - tmp = result = __alloca (cp - (str) + 3 + suffix_len); \ - cp = (str); \ - while (*cp != '\0') \ - *tmp++ = __toupper_l (*cp++, _nl_C_locobj_ptr); \ - if (cnt < 2) \ - { \ - *tmp++ = '/'; \ - if (cnt < 1) \ - { \ - *tmp++ = '/'; \ - if (suffix_len != 0) \ - tmp = __mempcpy (tmp, suffix, suffix_len); \ - } \ - } \ - *tmp = '\0'; \ - result; \ - }) - +/* Convert NAME of NAME_LEN bytes to the form expected by the gconv + functions, including the trailing slashes if necessary. The caller + has to free the returned string. Return NULL on allocation + failure. */ +char *__gconv_norm_add_slashes (const char *name, size_t name_len, + const char *suffix) + attribute_hidden; /* Return in *HANDLE decriptor for transformation from FROMSET to TOSET. */ extern int __gconv_open (const char *toset, const char *fromset, diff --git a/iconv/norm_add_slashes.c b/iconv/norm_add_slashes.c new file mode 100644 index 0000000..4e7d09a --- /dev/null +++ b/iconv/norm_add_slashes.c @@ -0,0 +1,53 @@ +/* Normalize the charset name and add a suffix with slashes. + Copyright (C) 1997-2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#define CHAR_ARRAY_INITIAL_SIZE 0 +#include + +char * +__gconv_norm_add_slashes (const char *name, size_t name_len, + const char *suffix) +{ + size_t cnt = 0; + for (size_t i = 0; i < name_len; i++) + if (name[i] == '/') + cnt++; + + struct char_array result; + if (!char_array_init_str_size (&result, name, name_len)) + return NULL; + + for (size_t i = 0; i < char_array_length (&result); i++) + *char_array_at (&result, i) = __toupper_l (name[i], _nl_C_locobj_ptr); + + if (cnt < 2) + { + if (!char_array_append_str (&result, "/")) + return NULL; + if (cnt < 1) + { + if (!char_array_append_str (&result, "/") + | !char_array_append_str (&result, suffix)) + return NULL; + } + } + + return char_array_finalize (&result, NULL); +} diff --git a/intl/dcigettext.c b/intl/dcigettext.c index d97746c..49127d0 100644 --- a/intl/dcigettext.c +++ b/intl/dcigettext.c @@ -1123,25 +1123,24 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, { size_t len; char *charset; - const char *outcharset; + char *outcharset; charsetstr += strlen ("charset="); len = strcspn (charsetstr, " \t\n"); - charset = (char *) alloca (len + 1); -# if defined _LIBC || HAVE_MEMPCPY - *((char *) mempcpy (charset, charsetstr, len)) = '\0'; -# else - memcpy (charset, charsetstr, len); - charset[len] = '\0'; -# endif - - outcharset = encoding; - # ifdef _LIBC /* We always want to use transliteration. */ - outcharset = norm_add_slashes (outcharset, "TRANSLIT"); - charset = norm_add_slashes (charset, ""); + charset = __gconv_norm_add_slashes (charsetstr, len, ""); + outcharset = __gconv_norm_add_slashes + (encoding, strlen (encoding), "TRANSLIT"); + if (charset == NULL || outcharset == NULL) + { + free ((char *) encoding); + free (outcharset); + free (charset); + goto unlock_fail; + } + int r = __gconv_open (outcharset, charset, &convd->conv, GCONV_AVOID_NOCONV); if (__builtin_expect (r != __GCONV_OK, 0)) @@ -1153,6 +1152,8 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, { gl_rwlock_unlock (domain->conversions_lock); free ((char *) encoding); + free (outcharset); + free (charset); return NULL; } @@ -1165,27 +1166,31 @@ _nl_find_msg (struct loaded_l10nfile *domain_file, # if (((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || __GLIBC__ > 2) \ && !defined __UCLIBC__) \ || _LIBICONV_VERSION >= 0x0105 + charset = strndup (charsetstr, len); if (strchr (outcharset, '/') == NULL) { - char *tmp; - - len = strlen (outcharset); - tmp = (char *) alloca (len + 10 + 1); - memcpy (tmp, outcharset, len); - memcpy (tmp + len, "//TRANSLIT", 10 + 1); - outcharset = tmp; - - convd->conv = iconv_open (outcharset, charset); - - freea (outcharset); + if (asprintf (&outcharset, "%s//TRANSLIT", + encoding) < 0) + outcharset = NULL; } else + outcharset = strdup (encoding); + if (charset == NULL || outcharset == NULL) + { + gl_rwlock_unlock (domain->conversions_lock); + free (outcharset); + free (charset); + free ((char *) encoding); + return NULL; + } # endif - convd->conv = iconv_open (outcharset, charset); + convd->conv = iconv_open (outcharset, charset); # endif # endif - - freea (charset); + free (outcharset); + free (charset); + /* Do not free encoding here because + convd->encoding takes ownership. */ } } } diff --git a/wcsmbs/wcsmbsload.c b/wcsmbs/wcsmbsload.c index 656cc0a..cf7f815 100644 --- a/wcsmbs/wcsmbsload.c +++ b/wcsmbs/wcsmbsload.c @@ -160,7 +160,6 @@ __wcsmbs_load_conv (struct __locale_data *new_category) { /* We must find the real functions. */ const char *charset_name; - const char *complete_name; struct gconv_fcts *new_fcts; int use_translit; @@ -177,8 +176,11 @@ __wcsmbs_load_conv (struct __locale_data *new_category) /* Normalize the name and add the slashes necessary for a complete lookup. */ - complete_name = norm_add_slashes (charset_name, - use_translit ? "TRANSLIT" : ""); + char *complete_name = __gconv_norm_add_slashes + (charset_name, strlen (charset_name), + use_translit ? "TRANSLIT" : ""); + if (complete_name ==NULL) + goto failed; /* It is not necessary to use transliteration in this direction since the internal character set is supposed to be able to @@ -188,6 +190,7 @@ __wcsmbs_load_conv (struct __locale_data *new_category) if (new_fcts->towc != NULL) new_fcts->tomb = __wcsmbs_getfct (complete_name, "INTERNAL", &new_fcts->tomb_nsteps); + free (complete_name); /* If any of the conversion functions is not available we don't use any since this would mean we cannot convert back and