From patchwork Mon Feb 5 13:27:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869273 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89967-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="s4A8QsFm"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpLq30F0z9sRV for ; Tue, 6 Feb 2018 00:28:18 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=b+NaS2QgjWlHKnWx4Mm5TVoa0TLppJI aRuhcEteWcCZ7K0Q3gWdiz/+Yt4Cs5F1y+nnKFnnVPduK1JDJW4HYFVjAcuPgkGJ jllS+K9kqLgydwHJ4i/pkJcm7EmL177RQskC7xUVwtHOHE2pvgrj5YVwkOsmd9gF mpoEpT5MVHqI= 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:subject:date:message-id:in-reply-to :references; s=default; bh=J29UxcNvtjMB2yon3NZSDlpzDag=; b=s4A8Q sFmJGCODf7t+uTn9D+wdiuiaUyf/Xwz7Q/2eEkQwNgGc4OOTCahftkgP360LBclo aE2JhxCO9XPxn4esF/rEsiWeFy8+19ZY6qvEoDvpfMMC6YS2hGd/TARYRLbIII8O DxmVPzwISSfIpTkch6jrjUF/EzIjSyH44T7fVY= Received: (qmail 32651 invoked by alias); 5 Feb 2018 13:27:52 -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 32421 invoked by uid 89); 5 Feb 2018 13:27:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=abcd X-HELO: mail-qt0-f173.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:subject:date:message-id:in-reply-to :references; bh=wmqwkj2V5NWfgk/XhLxR2etH4qH0g/dQhftXvNYeBS0=; b=nl+svEq7LCl53K1Ox6eyV+AyEvZQE8S8Ntu+3KhvAtjrKkhXnQfczP4viLXjEy5xVD czAoQAiioytA+osqMWoQX6XEe7OjqDPxCmU2c3By5ykJTLryS/A0MMH4++bQqT2M3woh ExR+HQzJWeeyYpv7Sgkvx/nujLjN2YsbnYrU5klsTMAOEKbvTEk1o1s2NevCJW74AjhY QX+9a+aKRsY0iqdk7vJ6ABEtKl7aWb2Y9JTfoBNgb07MpfYcVCd54/3EYbUisyShZl43 D9KabfMBzXHZ4Tp+aiv5oL6TBdogTtF3pEmo/+z6HTlG404rqTL6f9yQnzsAMc4Q0LpO 2vug== X-Gm-Message-State: APf1xPBPEUavGKNRCVMN2X7ZDEJBagfZVN4znr9o0KfwWEwrb51YtRRC egJFM9+tCf6Wg1yIw08wHoMSPgCsrBU= X-Google-Smtp-Source: AH8x2277HVvp6mhBZ5RJf/f9BelJK4ILRPICMIL+WEwu2WI2Q/Tjzb2JBtumLQLsBq+fDLx+v+cd8Q== X-Received: by 10.200.58.97 with SMTP id w88mr17632242qte.236.1517837263247; Mon, 05 Feb 2018 05:27:43 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 01/12] malloc: Add specialized dynarray for C strings Date: Mon, 5 Feb 2018 11:27:23 -0200 Message-Id: <1517837254-19399-2-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-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 = "testig2" char_array_erase (&str, 5); // str = "123testig2"; char_array_prepend_str (&str, "123"); // len = 10; size_t len = char_array_length (&str); // str = "123testig2456"; char_array_append_str (&str, "456"); // str = "123test789"; 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. Signed-off-by: Adhemerval Zanella --- ChangeLog | 15 ++ malloc/Makefile | 4 +- malloc/Versions | 7 + malloc/char_array-impl.c | 57 ++++++++ malloc/char_array-skeleton.c | 288 +++++++++++++++++++++++++++++++++++++ malloc/char_array.h | 53 +++++++ malloc/dynarray.h | 9 ++ malloc/dynarray_overflow_failure.c | 31 ++++ malloc/malloc-internal.h | 14 ++ malloc/tst-char_array.c | 112 +++++++++++++++ 10 files changed, 589 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 diff --git a/malloc/Makefile b/malloc/Makefile index 17873e6..1b0b5c5 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -50,6 +50,7 @@ tests-internal += \ tst-dynarray \ tst-dynarray-fail \ tst-dynarray-at-fail \ + tst-char_array ifneq (no,$(have-tunables)) tests += tst-malloc-usable-tunables @@ -62,7 +63,7 @@ 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 \ @@ -72,6 +73,7 @@ routines = malloc morecore mcheck mtrace obstack reallocarray \ alloc_buffer_copy_bytes \ alloc_buffer_copy_string \ alloc_buffer_create_failure \ + char_array-impl install-lib := libmcheck.a non-lib.a := libmcheck.a diff --git a/malloc/Versions b/malloc/Versions index 2357cff..b21fe59 100644 --- a/malloc/Versions +++ b/malloc/Versions @@ -81,6 +81,7 @@ libc { # dynarray support __libc_dynarray_at_failure; + __libc_dynarray_overflow_failure; __libc_dynarray_emplace_enlarge; __libc_dynarray_finalize; __libc_dynarray_resize; @@ -92,5 +93,11 @@ libc { __libc_alloc_buffer_copy_bytes; __libc_alloc_buffer_copy_string; __libc_alloc_buffer_create_failure; + + # 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..3aef1f7 --- /dev/null +++ b/malloc/char_array-impl.c @@ -0,0 +1,57 @@ +/* Specialized dynarray for C strings. Implementation file. + Copyright (C) 2018 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..4d9e4c0 --- /dev/null +++ b/malloc/char_array-skeleton.c @@ -0,0 +1,288 @@ +/* Specialized dynarray for C strings. + Copyright (C) 2018 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 provides 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_append_char (struct char_array *array, char c); + 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 = "testig2" + char_array_erase (&str, 5); + + // str = "123testig2"; + char_array_prepend_str (&str, "123"); + + // len = 10; + size_t len = char_array_length (&str); + + // str = "123testig2456"; + char_array_append_str (&str, "456"); + + // str = "123test789"; + 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 (const struct char_array *array) +{ + return array->dynarray_header.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 (const 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)); +} + +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_set_array (struct char_array *array, const struct char_array *orig) +{ + return char_array_set_str_size (array, char_array_str (orig), + char_array_length (orig)); +} + +/* 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; +} + +/* Append the character 'c' on char_array 'array'. */ +__attribute__ ((unused, nonnull (1))) +static bool +char_array_append_char (struct char_array *array, char c) +{ + return char_array_append_str (array, (const char[]) { c, '\0' }); +} + +/* 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..93df0d9 --- /dev/null +++ b/malloc/char_array.h @@ -0,0 +1,53 @@ +/* Specialized dynarray for C strings. Shared definitions. + Copyright (C) 2018 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 0b171da..fd8d218 100644 --- a/malloc/dynarray.h +++ b/malloc/dynarray.h @@ -168,12 +168,21 @@ bool __libc_dynarray_finalize (struct dynarray_header *list, void *scratch, void __libc_dynarray_at_failure (size_t size, size_t index) __attribute__ ((noreturn)); +/* 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)); + #ifndef _ISOMAC libc_hidden_proto (__libc_dynarray_emplace_enlarge) libc_hidden_proto (__libc_dynarray_resize) libc_hidden_proto (__libc_dynarray_resize_clear) libc_hidden_proto (__libc_dynarray_finalize) libc_hidden_proto (__libc_dynarray_at_failure) +libc_hidden_proto (__libc_dynarray_overflow_failure) + #endif #endif /* _DYNARRAY_H */ diff --git a/malloc/dynarray_overflow_failure.c b/malloc/dynarray_overflow_failure.c new file mode 100644 index 0000000..2bcef25 --- /dev/null +++ b/malloc/dynarray_overflow_failure.c @@ -0,0 +1,31 @@ +/* Report an dynamic array size overflow condition. + Copyright (C) 2018 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 ad05450..352db0bf 100644 --- a/malloc/malloc-internal.h +++ b/malloc/malloc-internal.h @@ -91,4 +91,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 __GNUC__ >= 5 + 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..745ecf4 --- /dev/null +++ b/malloc/tst-char_array.c @@ -0,0 +1,112 @@ +/* Test for char_array. + Copyright (C) 2018 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); + TEST_VERIFY_EXIT (char_array_append_char (&str, '4')); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "123test4") == 0); + char_array_free (&str); + } + + return 0; +} + +#include From patchwork Mon Feb 5 13:27:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869274 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89968-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="c3mO2grk"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpM06VtLz9s8J for ; Tue, 6 Feb 2018 00:28:28 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=y7iFiI/pLBCHU3CWPUBn/mxstjaf//R KC7TtvletbipPHowzcz5z0SsBLz8R5utMUWXlCXwxuT/sthk8lP9wE76t6fCaR2X 4G2Wz5VryjatAhsf+cHDLX1hv1CBztCCgJCqjJ5Hsfo6Y8Hze2W4qWRZmYriBwlY RwvUHy51/RnI= 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:subject:date:message-id:in-reply-to :references; s=default; bh=qlIrv6hNMumRaz53ef29NZNmWhY=; b=c3mO2 grkaEgibL5irAQ1WIaRuSgt3UZb7rozHyehgRd0EeTr43kPvrxMXY5wNhEllZgZu cDcMk4qs4C5eqt6nDO+H9KWFUkpTBVenCs2ipvkOZqUwpXUnPcClDd34ZWGIEMzl R+G/pZfpvKa3f1u+qKk6SeYGBlV/WVYDJ6psSY= Received: (qmail 32714 invoked by alias); 5 Feb 2018 13:27:52 -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 32490 invoked by uid 89); 5 Feb 2018 13:27:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, 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=Stick, 4619, 5138, 82535 X-HELO: mail-qk0-f171.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:subject:date:message-id:in-reply-to :references; bh=q+ZyB/M0RrUIIQbve1XTkMsT+ilIVxl+R9gE4qHhQh4=; b=QYvVwuFLnVR5SSG/0sr5+YyPcKRePu3VrBK58MSp1u1WI3ErLW2Gn0bprIHQd4jQqu 8XOUzUIbLGcfEGnokLQ5jDLL9DxAWpe1jZD+mw0f1wanq8q6W7ecqV6OW/yxuSG/g08w bjumXnEm6zt/mhe2tcAYHjG5gczhWqhgZWrx1N6S7rTesIFDLMQekMTDUFEVFtrotAX5 JupUhJbcCItIziBdhfA51YZ8GBt7gX2sCYixrrHrmygqDW7uetyHXot5zZeK2lfaJ4fU K9/nm8PQkra1D2+qEUSMkref5zYLXMhXzRJ6ZNQDlAmGwbNKPcwLytdybPsvh9S2sbou dfew== X-Gm-Message-State: APf1xPCn0klecqJyejN3Pi+qh3v7jPKfLBAHsjixz3d8EYRpdmYxWf2n efZOx5z89sQNaT4BblzL6Ot27zjntAg= X-Google-Smtp-Source: AH8x2253e3lOGIuS9qBhG/D5SaRdttmT3HpwBNdtWlL1/IiQLOWyXrnP/94ZqDb8dbUAJFK3kn6BVw== X-Received: by 10.55.98.206 with SMTP id w197mr12956365qkb.202.1517837264776; Mon, 05 Feb 2018 05:27:44 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 02/12] posix: Use char_array for internal glob dirname Date: Mon, 5 Feb 2018 11:27:24 -0200 Message-Id: <1517837254-19399-3-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> This is the first patch of the set to remove alloca usage on glob implementation. Internal path to search for file might expand to a non static directory derived from pattern for some difference cases (GLOB_NOESCAPE, GNU GLOB_TILDE) and to allow a non-static dirname path glob uses a lot of boilerplate code to manage the buffer (which is either allocated using alloca or malloc depending both to size requested and the total alloca_used). The patch changes to use the char_array struct with the default size (256 bytes). It simplifies all the allocation code by using char_array one and every internal buffer access is done using char_array provided functions. No functional changes are expected. Checked on x86_64-linux-gnu. * posix/globc.c (glob): Use char_array for dirname. Signed-off-by: Adhemerval Zanella --- ChangeLog | 2 + posix/glob.c | 273 ++++++++++++++++++++++++----------------------------------- 2 files changed, 112 insertions(+), 163 deletions(-) diff --git a/posix/glob.c b/posix/glob.c index 8444b2f..4814d67 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -77,6 +77,7 @@ #include #include #include +#include static const char *next_brace_sub (const char *begin, int flags) __THROWNL; @@ -288,16 +289,15 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), glob_t *pglob) { const char *filename; - char *dirname = NULL; size_t dirlen; int status; size_t oldcount; int meta; - int dirname_modified; - int malloc_dirname = 0; + bool dirname_modified; glob_t dirs; int retval = 0; size_t alloca_used = 0; + struct char_array dirname; if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) { @@ -305,6 +305,10 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), return -1; } + /* Default char array is stack allocated, so there is no need to check + if setting the initial '\0' succeeds. */ + char_array_init_empty (&dirname); + /* POSIX requires all slashes to be matched. This means that with a trailing slash we must match only directories. */ if (pattern[0] && pattern[strlen (pattern) - 1] == '/') @@ -325,12 +329,12 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), size_t i; if (pglob->gl_offs >= ~((size_t) 0) / sizeof (char *)) - return GLOB_NOSPACE; + goto err_nospace; pglob->gl_pathv = (char **) malloc ((pglob->gl_offs + 1) * sizeof (char *)); if (pglob->gl_pathv == NULL) - return GLOB_NOSPACE; + goto err_nospace; for (i = 0; i <= pglob->gl_offs; ++i) pglob->gl_pathv[i] = NULL; @@ -382,7 +386,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { onealt = malloc (pattern_len); if (onealt == NULL) - return GLOB_NOSPACE; + goto err_nospace; } /* We know the prefix for all sub-patterns. */ @@ -444,7 +448,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), globfree (pglob); pglob->gl_pathc = 0; } - return result; + retval = result; + goto out; } if (*next == '}') @@ -461,9 +466,10 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (pglob->gl_pathc != firstc) /* We found some entries. */ - return 0; + retval = 0; else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) - return GLOB_NOMATCH; + retval = GLOB_NOMATCH; + goto out; } } @@ -482,14 +488,15 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), filename = strchr (pattern, ':'); #endif /* __MSDOS__ || WINDOWS32 */ - dirname_modified = 0; + dirname_modified = false; if (filename == NULL) { /* This can mean two things: a simple name or "~name". The latter case is nothing but a notation for a directory. */ if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~') { - dirname = (char *) pattern; + if (!char_array_set_str (&dirname, pattern)) + goto err_nospace; dirlen = strlen (pattern); /* Set FILENAME to NULL as a special flag. This is ugly but @@ -506,7 +513,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), } filename = pattern; - dirname = (char *) "."; + if (!char_array_set_str (&dirname, ".")) + goto err_nospace; dirlen = 0; } } @@ -515,13 +523,13 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), && (flags & GLOB_NOESCAPE) == 0)) { /* "/pattern" or "\\/pattern". */ - dirname = (char *) "/"; + if (!char_array_set_str (&dirname, "/")) + goto err_nospace; dirlen = 1; ++filename; } else { - char *newp; dirlen = filename - pattern; #if defined __MSDOS__ || defined WINDOWS32 if (*filename == ':' @@ -535,31 +543,25 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), /* For now, disallow wildcards in the drive spec, to prevent infinite recursion in glob. */ if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE))) - return GLOB_NOMATCH; + { + retval = GLOB_NOMATCH; + goto out; + } /* If this is "d:pattern", we need to copy ':' to DIRNAME as well. If it's "d:/pattern", don't remove the slash from "d:/", since "d:" and "d:/" are not the same.*/ } #endif - - if (glob_use_alloca (alloca_used, dirlen + 1)) - newp = alloca_account (dirlen + 1, alloca_used); - else - { - newp = malloc (dirlen + 1); - if (newp == NULL) - return GLOB_NOSPACE; - malloc_dirname = 1; - } - *((char *) mempcpy (newp, pattern, dirlen)) = '\0'; - dirname = newp; + if (!char_array_set_str_size (&dirname, pattern, dirlen)) + goto err_nospace; ++filename; #if defined __MSDOS__ || defined WINDOWS32 bool drive_root = (dirlen > 1 - && (dirname[dirlen - 1] == ':' - || (dirlen > 2 && dirname[dirlen - 2] == ':' - && dirname[dirlen - 1] == '/'))); + && (char_array_pos (&dirname, dirlen - 1) != ':' + || (dirlen > 2 + && char_array_pos (&dirname, dirlen - 2) != ':' + && char_array_pos (&dirname, dirlen - 1) != '/'))); #else bool drive_root = false; #endif @@ -568,20 +570,24 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), /* "pattern/". Expand "pattern", appending slashes. */ { int orig_flags = flags; - if (!(flags & GLOB_NOESCAPE) && dirname[dirlen - 1] == '\\') + if (!(flags & GLOB_NOESCAPE) + && char_array_pos (&dirname, dirlen - 1) == '\\') { /* "pattern\\/". Remove the final backslash if it hasn't been quoted. */ - char *p = (char *) &dirname[dirlen - 1]; - - while (p > dirname && p[-1] == '\\') --p; - if ((&dirname[dirlen] - p) & 1) + size_t p = dirlen - 1; + while (p > 0 && char_array_pos (&dirname, p - 1) == '\\') --p; + if ((dirlen - p) & 1) { - *(char *) &dirname[--dirlen] = '\0'; + /* Since we are shrinking the array, there is no need to + check the function return. */ + dirlen -= 1; + char_array_crop (&dirname, dirlen); flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC); } } - int val = __glob (dirname, flags | GLOB_MARK, errfunc, pglob); + int val = __glob (char_array_str (&dirname), flags | GLOB_MARK, + errfunc, pglob); if (val == 0) pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK)); @@ -598,11 +604,14 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), } } - if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~') + if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) + && char_array_pos (&dirname, 0) == '~') { - if (dirname[1] == '\0' || dirname[1] == '/' - || (!(flags & GLOB_NOESCAPE) && dirname[1] == '\\' - && (dirname[2] == '\0' || dirname[2] == '/'))) + if (char_array_pos (&dirname, 1) == '\0' + || char_array_pos (&dirname, 1) == '/' + || (!(flags & GLOB_NOESCAPE) && char_array_pos (&dirname, 1) == '\\' + && (char_array_pos (&dirname, 2) == '\0' + || char_array_pos (&dirname, 2) == '/'))) { /* Look up home directory. */ char *home_dir = getenv ("HOME"); @@ -653,10 +662,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (err != ERANGE) break; if (!scratch_buffer_grow (&s)) - { - retval = GLOB_NOSPACE; - goto out; - } + goto err_nospace; } if (err == 0) { @@ -665,10 +671,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), } scratch_buffer_free (&s); if (err == 0 && home_dir == NULL) - { - retval = GLOB_NOSPACE; - goto out; - } + goto err_nospace; #endif /* WINDOWS32 */ } if (home_dir == NULL || home_dir[0] == '\0') @@ -687,53 +690,26 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), } } /* Now construct the full directory. */ - if (dirname[1] == '\0') + if (char_array_pos (&dirname, 1) == '\0') { - if (__glibc_unlikely (malloc_dirname)) - free (dirname); - - dirname = home_dir; - dirlen = strlen (dirname); - malloc_dirname = malloc_home_dir; + if (!char_array_set_str (&dirname, home_dir)) + goto err_nospace; + dirlen = char_array_size (&dirname) - 1; } else { - char *newp; - size_t home_len = strlen (home_dir); - int use_alloca = glob_use_alloca (alloca_used, home_len + dirlen); - if (use_alloca) - newp = alloca_account (home_len + dirlen, alloca_used); - else - { - newp = malloc (home_len + dirlen); - if (newp == NULL) - { - if (__glibc_unlikely (malloc_home_dir)) - free (home_dir); - retval = GLOB_NOSPACE; - goto out; - } - } - - mempcpy (mempcpy (newp, home_dir, home_len), - &dirname[1], dirlen); - - if (__glibc_unlikely (malloc_dirname)) - free (dirname); - - dirname = newp; - dirlen += home_len - 1; - malloc_dirname = !use_alloca; - - if (__glibc_unlikely (malloc_home_dir)) - free (home_dir); + /* Replaces '~' by the obtained HOME dir. */ + char_array_erase (&dirname, 0); + if (!char_array_prepend_str (&dirname, home_dir)) + goto err_nospace; } - dirname_modified = 1; + dirname_modified = true; } else { #ifndef WINDOWS32 - char *end_name = strchr (dirname, '/'); + char *dirnamestr = char_array_at (&dirname, 0); + char *end_name = strchr (dirnamestr, '/'); char *user_name; int malloc_user_name = 0; char *unescape = NULL; @@ -742,23 +718,23 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { if (end_name == NULL) { - unescape = strchr (dirname, '\\'); + unescape = strchr (dirnamestr, '\\'); if (unescape) end_name = strchr (unescape, '\0'); } else - unescape = memchr (dirname, '\\', end_name - dirname); + unescape = memchr (dirnamestr, '\\', end_name - dirnamestr); } if (end_name == NULL) - user_name = dirname + 1; + user_name = dirnamestr + 1; else { char *newp; - if (glob_use_alloca (alloca_used, end_name - dirname)) - newp = alloca_account (end_name - dirname, alloca_used); + if (glob_use_alloca (alloca_used, end_name - dirnamestr)) + newp = alloca_account (end_name - dirnamestr, alloca_used); else { - newp = malloc (end_name - dirname); + newp = malloc (end_name - dirnamestr); if (newp == NULL) { retval = GLOB_NOSPACE; @@ -768,8 +744,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), } if (unescape != NULL) { - char *p = mempcpy (newp, dirname + 1, - unescape - dirname - 1); + char *p = mempcpy (newp, dirnamestr + 1, + unescape - dirnamestr - 1); char *q = unescape; while (q != end_name) { @@ -791,7 +767,8 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), *p = '\0'; } else - *((char *) mempcpy (newp, dirname + 1, end_name - dirname - 1)) + *((char *) mempcpy (newp, dirnamestr + 1, + end_name - dirnamestr - 1)) = '\0'; user_name = newp; } @@ -825,35 +802,13 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), /* If we found a home directory use this. */ if (p != NULL) { - size_t home_len = strlen (p->pw_dir); - size_t rest_len = end_name == NULL ? 0 : strlen (end_name); - char *d; - - if (__glibc_unlikely (malloc_dirname)) - free (dirname); - malloc_dirname = 0; - - if (glob_use_alloca (alloca_used, home_len + rest_len + 1)) - dirname = alloca_account (home_len + rest_len + 1, - alloca_used); - else + if (!char_array_set_str (&dirname, p->pw_dir)) { - dirname = malloc (home_len + rest_len + 1); - if (dirname == NULL) - { - scratch_buffer_free (&pwtmpbuf); - retval = GLOB_NOSPACE; - goto out; - } - malloc_dirname = 1; + scratch_buffer_free (&pwtmpbuf); + goto err_nospace; } - d = mempcpy (dirname, p->pw_dir, home_len); - if (end_name != NULL) - d = mempcpy (d, end_name, rest_len); - *d = '\0'; - - dirlen = home_len + rest_len; - dirname_modified = 1; + dirlen = strlen (p->pw_dir); + dirname_modified = true; } else { @@ -894,37 +849,32 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), goto nospace; pglob->gl_pathv = new_gl_pathv; - if (flags & GLOB_MARK && is_dir (dirname, flags, pglob)) + if (flags & GLOB_MARK + && is_dir (char_array_str (&dirname), flags, pglob)) { char *p; pglob->gl_pathv[newcount] = malloc (dirlen + 2); if (pglob->gl_pathv[newcount] == NULL) goto nospace; - p = mempcpy (pglob->gl_pathv[newcount], dirname, dirlen); + p = mempcpy (pglob->gl_pathv[newcount], + char_array_str (&dirname), dirlen); p[0] = '/'; p[1] = '\0'; - if (__glibc_unlikely (malloc_dirname)) - free (dirname); } else { - if (__glibc_unlikely (malloc_dirname)) - pglob->gl_pathv[newcount] = dirname; - else - { - pglob->gl_pathv[newcount] = strdup (dirname); - if (pglob->gl_pathv[newcount] == NULL) - goto nospace; - } + pglob->gl_pathv[newcount] = strdup (char_array_str (&dirname)); + if (pglob->gl_pathv[newcount] == NULL) + goto nospace; } pglob->gl_pathv[++newcount] = NULL; ++pglob->gl_pathc; pglob->gl_flags = flags; - - return 0; + goto out; } - meta = __glob_pattern_type (dirname, !(flags & GLOB_NOESCAPE)); + meta = __glob_pattern_type (char_array_str (&dirname), + !(flags & GLOB_NOESCAPE)); /* meta is 1 if correct glob pattern containing metacharacters. If meta has bit (1 << 2) set, it means there was an unterminated [ which we handle the same, using fnmatch. Broken unterminated @@ -937,15 +887,15 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), the pattern in each directory found. */ size_t i; - if (!(flags & GLOB_NOESCAPE) && dirlen > 0 && dirname[dirlen - 1] == '\\') + if (!(flags & GLOB_NOESCAPE) && dirlen > 0 + && char_array_pos (&dirname, dirlen - 1) == '\\') { /* "foo\\/bar". Remove the final backslash from dirname if it has not been quoted. */ - char *p = (char *) &dirname[dirlen - 1]; - - while (p > dirname && p[-1] == '\\') --p; - if ((&dirname[dirlen] - p) & 1) - *(char *) &dirname[--dirlen] = '\0'; + size_t p = dirlen - 1; + while (p > 0 && char_array_pos (&dirname, p - 1) == '\\') --p; + if ((dirlen - p) & 1) + char_array_crop (&dirname, --dirlen); } if (__glibc_unlikely ((flags & GLOB_ALTDIRFUNC) != 0)) @@ -959,7 +909,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), dirs.gl_lstat = pglob->gl_lstat; } - status = __glob (dirname, + status = __glob (char_array_str (&dirname), ((flags & (GLOB_ERR | GLOB_NOESCAPE | GLOB_ALTDIRFUNC)) | GLOB_NOSORT | GLOB_ONLYDIR), errfunc, &dirs); @@ -1006,8 +956,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), globfree (&dirs); globfree (pglob); pglob->gl_pathc = 0; - retval = GLOB_NOSPACE; - goto out; + goto err_nospace; } } @@ -1029,8 +978,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { nospace2: globfree (&dirs); - retval = GLOB_NOSPACE; - goto out; + goto err_nospace; } new_gl_pathv = realloc (pglob->gl_pathv, @@ -1045,8 +993,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), globfree (&dirs); globfree (pglob); pglob->gl_pathc = 0; - retval = GLOB_NOSPACE; - goto out; + goto err_nospace; } ++pglob->gl_pathc; @@ -1072,7 +1019,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (meta & GLOBPAT_BACKSLASH) { - char *p = strchr (dirname, '\\'), *q; + char *p = strchr (char_array_str (&dirname), '\\'), *q; /* We need to unescape the dirname string. It is certainly allocated by alloca, as otherwise filename would be NULL or dirname wouldn't contain backslashes. */ @@ -1089,12 +1036,12 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), ++q; } while (*p++ != '\0'); - dirname_modified = 1; + dirname_modified = true; } if (dirname_modified) flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC); - status = glob_in_dir (filename, dirname, flags, errfunc, pglob, - alloca_used); + status = glob_in_dir (filename, char_array_str (&dirname), flags, + errfunc, pglob, alloca_used); if (status != 0) { if (status == GLOB_NOMATCH && flags != orig_flags @@ -1112,14 +1059,13 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (dirlen > 0) { /* Stick the directory on the front of each name. */ - if (prefix_array (dirname, + if (prefix_array (char_array_str (&dirname), &pglob->gl_pathv[old_pathc + pglob->gl_offs], pglob->gl_pathc - old_pathc)) { globfree (pglob); pglob->gl_pathc = 0; - retval = GLOB_NOSPACE; - goto out; + goto err_nospace; } } } @@ -1138,8 +1084,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { globfree (pglob); pglob->gl_pathc = 0; - retval = GLOB_NOSPACE; - goto out; + goto err_nospace; } strcpy (&new[len - 2], "/"); pglob->gl_pathv[i] = new; @@ -1155,10 +1100,12 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), } out: - if (__glibc_unlikely (malloc_dirname)) - free (dirname); - + char_array_free (&dirname); return retval; + + err_nospace: + char_array_free (&dirname); + return GLOB_NOSPACE; } #if defined _LIBC && !defined __glob versioned_symbol (libc, __glob, glob, GLIBC_2_27); From patchwork Mon Feb 5 13:27:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869271 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89965-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="gFpshpzC"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpLV2dn3z9t2l for ; Tue, 6 Feb 2018 00:28:01 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=rvvVlxitHPrNu6A5dYLelmHL1plDNKm DZQW/5BntXKAzi7WJ4G79E5jXbPLwoHNeUXYBPXy/FYsLpXpnRV56eL8XMoQyCBX f4wmkcjtB4sOsgN7XMUanUpBBE6brYX4DiLVC7Xsc5snkNJQ4703SRoryJXwc2RG QpbQYBNonyEI= 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:subject:date:message-id:in-reply-to :references; s=default; bh=C6mDyClMXS7iK5toL9RHnPotmgY=; b=gFpsh pzCncQuXref0aMoAlVyNbjAD94B5ss6twHSjjiRseu9bw7TScg1OYew95S5A/Ram 8crk3XBXeWSnOTED1kkGe+XSRPAkjR1xdtUWHGsChpUy4FKVI8Fu+1bLdLkFLarS a8YeLU+ZMR0h+DEbbKM9J79C5dLJTEkB/3oIA0= Received: (qmail 32550 invoked by alias); 5 Feb 2018 13:27:52 -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 32279 invoked by uid 89); 5 Feb 2018 13:27:49 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.6 required=5.0 tests=AWL, 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=4677, Allocate, our X-HELO: mail-qk0-f196.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:subject:date:message-id:in-reply-to :references; bh=kvukgy+q8OckB3mu7WbWUW7oiRoMqNr7ErlROk3fl28=; b=E2hOKQG6NcAEXF4aFbrLZ97j6pTWEjjbAy4JLQnO2tEvRuv+5l+XGnu6WFy6XR8C6l lF4J4vnX0nUPFF1hcsO4zdfbrPN+pnZNhbSXeAe6BnmqHaQTALdOpoPHlTrC3rU5XL11 1wQ7Fg7juEozgetnhKbpJvDX7/++sWDa2B0HDRebV89ufNaGkstW9I0Jd3f52ZdSkCc4 af5z0BGmEXy38l8IW/dhat6MsPwCDlJFI+TfSuv3vwxlMsSKVKVlPY0kJbchF17p9iGX Zp7RWFkScoepdjR8tSWCmO2kCibRikr5MJSUSVKu8O1uunDEIKCvOCV2MwxFhYPXEJA8 EJWQ== X-Gm-Message-State: APf1xPBGf/Q9ivy/l1kkdwRo3EkFnZUT7yHpd8FDNSoO9OUUkAQvFHPF dWa0xV/1hb5I/p4JK5xDSbvdL4TJwe0= X-Google-Smtp-Source: AH8x225LJbM+Bln6KRJESbZDfb4DjrCeWJXG0yzB3c2rdhFlXkIbaJ/wBtCk5LRyFrFFxZXFrOagdw== X-Received: by 10.55.40.98 with SMTP id o95mr23542561qkh.216.1517837266079; Mon, 05 Feb 2018 05:27:46 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 03/12] posix: Remove alloca usage for GLOB_BRACE on glob Date: Mon, 5 Feb 2018 11:27:25 -0200 Message-Id: <1517837254-19399-4-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> GNU GLOB_BRACE internal implementation constructs a new expression and calls glob recursively. It then requires a possible large temporary buffer place the new pattern. This patch removes the alloca/malloc usage and replaces it with char_array. Checked on x86_64-linux-gnu. * posix/glob.c (glob): Remove alloca usage for onealt. Signed-off-by: Adhemerval Zanella --- ChangeLog | 2 ++ posix/glob.c | 53 +++++++++++++++++++++++++++++------------------------ 2 files changed, 31 insertions(+), 24 deletions(-) diff --git a/posix/glob.c b/posix/glob.c index 4814d67..3e36eeb 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -372,25 +372,23 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), /* Allocate working buffer large enough for our work. Note that we have at least an opening and closing brace. */ size_t firstc; - char *alt_start; const char *p; const char *next; const char *rest; size_t rest_len; - char *onealt; - size_t pattern_len = strlen (pattern) - 1; - int alloca_onealt = glob_use_alloca (alloca_used, pattern_len); - if (alloca_onealt) - onealt = alloca_account (pattern_len, alloca_used); - else - { - onealt = malloc (pattern_len); - if (onealt == NULL) - goto err_nospace; - } + struct char_array onealt; /* We know the prefix for all sub-patterns. */ - alt_start = mempcpy (onealt, pattern, begin - pattern); + ptrdiff_t onealtlen = begin - pattern; + if (!char_array_init_str_size (&onealt, pattern, onealtlen)) + { + if (!(flags & GLOB_APPEND)) + { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + } + goto err_nospace; + } /* Find the first sub-pattern and at the same time find the rest after the closing brace. */ @@ -398,9 +396,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (next == NULL) { /* It is an invalid expression. */ - illegal_brace: - if (__glibc_unlikely (!alloca_onealt)) - free (onealt); + char_array_free (&onealt); flags &= ~GLOB_BRACE; goto no_brace; } @@ -411,8 +407,12 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), { rest = next_brace_sub (rest + 1, flags); if (rest == NULL) - /* It is an illegal expression. */ - goto illegal_brace; + { + /* It is an illegal expression. */ + char_array_free (&onealt); + flags &= ~GLOB_BRACE; + goto no_brace; + } } /* Please note that we now can be sure the brace expression is well-formed. */ @@ -431,9 +431,16 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), int result; /* Construct the new glob expression. */ - mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len); + ptrdiff_t nextlen = next - p; + if (!char_array_replace_str_pos (&onealt, onealtlen, p, nextlen) + || !char_array_replace_str_pos (&onealt, onealtlen + nextlen, + rest, rest_len)) + { + char_array_free (&onealt); + goto err_nospace; + } - result = __glob (onealt, + result = __glob (char_array_str (&onealt), ((flags & ~(GLOB_NOCHECK | GLOB_NOMAGIC)) | GLOB_APPEND), errfunc, pglob); @@ -441,8 +448,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), /* If we got an error, return it. */ if (result && result != GLOB_NOMATCH) { - if (__glibc_unlikely (!alloca_onealt)) - free (onealt); + char_array_free (&onealt); if (!(flags & GLOB_APPEND)) { globfree (pglob); @@ -461,8 +467,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), assert (next != NULL); } - if (__glibc_unlikely (!alloca_onealt)) - free (onealt); + char_array_free (&onealt); if (pglob->gl_pathc != firstc) /* We found some entries. */ From patchwork Mon Feb 5 13:27:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869272 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89966-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="dH3ozIfs"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpLf0Qtkz9t2l for ; Tue, 6 Feb 2018 00:28:09 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=HD6lFU7n4K20aif7Mwxo58tBeIvPCJD IevpTzG6JxOj3jLoy7gqC11qnhKcN94J58UrX4tQkPTDtOQsJ9I/FZqoT8J8qDRz ncHnxhJcbiLpBiSxFNWbuAgU37NqgMjct+N/UDnXbthpTPdvMlzQ58raBapKnMAM gIyldX9EjaBI= 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:subject:date:message-id:in-reply-to :references; s=default; bh=rJRqwKrm+eQge2FmttgxJRmdlQY=; b=dH3oz IfsKZyv8zPKxtvLjfre8d12ZDFa3H1svH5Oxbn1W4D1NNbMox/FfHjHYlaAFwy5i UV83GU1sgPRAc5vUmgb45oKFbSenhYCC39LPhWDo5D1yUgtGyP7TPQqaS7jmZ9sK Wu/CtGRj8QFADdF+QK91q8ZgZSCCYnA5GUjvsA= Received: (qmail 32606 invoked by alias); 5 Feb 2018 13:27:52 -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 32436 invoked by uid 89); 5 Feb 2018 13:27:51 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, 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=Hx-languages-length:2061, 11986 X-HELO: mail-qt0-f196.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:subject:date:message-id:in-reply-to :references; bh=SSUJrWbbpI9id/8L9RFSdToPch7srdxwjRZVerMraMY=; b=HPM+Y9Gzaskis5zXsaPpDfipDuxMKw6930VorEfEpIm0iA/UHHYhBNMf73V7/KFdc5 xJM3hK8o3hnT2dXZjFKJaX1WUyILAiMa3VUkVmGv8bzxhUCN6rAYHKt2Xk0CI6eFKyAX nz1/mctcWk1Yo5ZaTCgx4mRa5t3QornEbaorK8eHhmBHvcz0ZxhcmC1lgDyLBHb/Zibm BRL7Iz7X4wUnao8VYP+rChsRJ9Quz5rN8CxOeN/QfWBF8NDv5F/ak2QAUDzkxzhzv2nP nEDFB5kOHjjHJ0OsaY9pKFgohmtzvVwtx3TnQcc7DcSlkjGpmrL/mlKiMroQBSas8ygp I79w== X-Gm-Message-State: AKwxytfLheY5B4Kd213lwYcYjvdkeJV0RIv+CWKTbizFHzkXyE0WjtC+ g1Xj3c5xhjD/n2dncwIXiPf9sUQgoN4= X-Google-Smtp-Source: AH8x226p+QLugD5GLOUgUmV4tu7u3LvNwT5Tt3W2tSTZQN4vQVysr2OYhkdO/m1Feco1nR2RAPjDZw== X-Received: by 10.237.55.132 with SMTP id j4mr32100989qtb.324.1517837267356; Mon, 05 Feb 2018 05:27:47 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 04/12] posix: Remove alloca usage on glob dirname Date: Mon, 5 Feb 2018 11:27:26 -0200 Message-Id: <1517837254-19399-5-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> This patch replaces the alloca/malloc usage for dirname creation by the char_array struct. Checked on x86_64-linux-gnu. * posix/glob.c (glob_in_dir): Remove alloca usage for fullname. Signed-off-by: Adhemerval Zanella --- ChangeLog | 2 ++ posix/glob.c | 28 +++++++++------------------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/posix/glob.c b/posix/glob.c index 3e36eeb..26af331 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -1198,7 +1198,6 @@ glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), glob_t *pglob, size_t alloca_used) { - size_t dirlen = strlen (directory); void *stream = NULL; # define GLOBNAMES_MEMBERS(nnames) \ struct globnames *next; size_t count; char *name[nnames]; @@ -1230,32 +1229,23 @@ glob_in_dir (const char *pattern, const char *directory, int flags, } else if (meta == GLOBPAT_NONE) { - size_t patlen = strlen (pattern); - size_t fullsize; - bool alloca_fullname - = (! size_add_wrapv (dirlen + 1, patlen + 1, &fullsize) - && glob_use_alloca (alloca_used, fullsize)); - char *fullname; - if (alloca_fullname) - fullname = alloca_account (fullsize, alloca_used); - else + struct char_array fullname; + + if (!char_array_init_str (&fullname, directory) + || !char_array_append_str (&fullname, "/") + || !char_array_append_str (&fullname, pattern)) { - fullname = malloc (fullsize); - if (fullname == NULL) - return GLOB_NOSPACE; + char_array_free (&fullname); + return GLOB_NOSPACE; } - mempcpy (mempcpy (mempcpy (fullname, directory, dirlen), - "/", 1), - pattern, patlen + 1); - if (glob_lstat (pglob, flags, fullname) == 0 + if (glob_lstat (pglob, flags, char_array_str (&fullname)) == 0 || errno == EOVERFLOW) /* We found this file to be existing. Now tell the rest of the function to copy this name into the result. */ flags |= GLOB_NOCHECK; - if (__glibc_unlikely (!alloca_fullname)) - free (fullname); + char_array_free (&fullname); } else { From patchwork Mon Feb 5 13:27:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869275 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89969-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="A4x64PqM"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpMF2jmTz9s8J for ; Tue, 6 Feb 2018 00:28:41 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=RoDuw88VH/VnKxiQQw9UPJQqjxTeKkp pWqAeyPpHlZVAhc26eDbw4s8TqPrYSMpKaGR8nRXqvDjEOA25gm5re3hulJBUSmE 6CXamObPJ/yXvl5jPnACbSLT7yDzqqLhg5rPCXalY+HvPct6wMyNlgFsdro6XkUL oF6Ao4m5dVcQ= 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:subject:date:message-id:in-reply-to :references; s=default; bh=WhU2oJ6DwxKfOC6uQ/M7yB/GXIU=; b=A4x64 PqMY1pFFYci4MFpWcNTzpSS+12WrtqzKnP7J2UrkgO17T0RlO2Upd/RKYAc0JwfI 1OWxWI9dd3btrtAJvTJ/N5eorsMAuHoXtIVtIrGsB1f3e7/fCtl9gP6pYotgDhpA F1wstwwERgerWqT8jVbIpeUQnyLVyWrCM9xFDs= Received: (qmail 32985 invoked by alias); 5 Feb 2018 13:27:54 -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 32769 invoked by uid 89); 5 Feb 2018 13:27:52 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, 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-qt0-f193.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:subject:date:message-id:in-reply-to :references; bh=8wnpdPwrnzEzLoN4Ilk9UZN+3OjwSpuIlTmotSHiRWE=; b=kRpIlMZPbvaB3fDV8E3h5dbY4HQtO/OODS0KWnoL35Jj9yDF19kUypSFDvZknwFF0C 84c51mayN4DVCXd99CqtNWk+zXsdQGQNdoU2CqYJVUaHrR3fu/+d2QYCrWermj+QP0Sc +JD/vCaushfSlCfcDegMjIWU03psfXcNVTK/3Q5GPYIqYQFQxp/JbZ13zL453U837n8s dzBAOfDclyvE3m2wKgq8Zefvfs9QsHtHbVPvRzGLQAsImy2qjQsteBWARnkocqmVvFHD q8+BGbQJiZMsfJdi/Hn5YaPaf9PWXOPQ/5arqSl6dWAbhWGAl3YLmLkQtDjLIw6qsiDh XgsQ== X-Gm-Message-State: AKwxytdhHQAtroaHFo2htCpTQfWRbGmcnBECClTcBRPZzqo+Bi66+7/A NcbmNQwrY2bX4b6M5qyD06CqQ3WjV20= X-Google-Smtp-Source: AH8x226EOPaV8TFLRD0ERU7cEuABYYgP3U+P8GqGKSHxvb3GoJRquxPIQUFgDqGwfFHwBlGc/uDXlw== X-Received: by 10.237.41.163 with SMTP id o32mr80498571qtd.80.1517837268721; Mon, 05 Feb 2018 05:27:48 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 05/12] posix: Use dynarray for globname in glob Date: Mon, 5 Feb 2018 11:27:27 -0200 Message-Id: <1517837254-19399-6-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> This patch uses dynarray at glob internal glob_in_dir function to manage the various matched patterns. It simplify and removes all the boilerplate buffer managements required. It also removes the glob_use_alloca, since it is not used anymore. Checked on x86_64-linux-gnu. * posix/glob.c (glob_in_dir): Use dynarray for globnames. --- ChangeLog | 2 + posix/glob.c | 127 +++++++++++++++++------------------------------------------ 2 files changed, 39 insertions(+), 90 deletions(-) diff --git a/posix/glob.c b/posix/glob.c index 26af331..2632e93 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -1189,6 +1189,21 @@ prefix_array (const char *dirname, char **array, size_t n) return 0; } +struct globnames_result +{ + char **names; + size_t length; +}; + +/* Create a dynamic array for C string representing the glob name found. */ +#define DYNARRAY_STRUCT globnames_array +#define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr) +#define DYNARRAY_ELEMENT char * +#define DYNARRAY_PREFIX globnames_array_ +#define DYNARRAY_FINAL_TYPE struct globnames_result +#define DYNARRAY_INITIAL_SIZE 64 +#include + /* Like 'glob', but PATTERN is a final pathname component, and matches are searched for in DIRECTORY. The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done. @@ -1199,25 +1214,13 @@ glob_in_dir (const char *pattern, const char *directory, int flags, glob_t *pglob, size_t alloca_used) { void *stream = NULL; -# define GLOBNAMES_MEMBERS(nnames) \ - struct globnames *next; size_t count; char *name[nnames]; - struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) }; - struct { GLOBNAMES_MEMBERS (64) } init_names_buf; - struct globnames *init_names = (struct globnames *) &init_names_buf; - struct globnames *names = init_names; - struct globnames *names_alloca = init_names; + struct globnames_array globnames; size_t nfound = 0; - size_t cur = 0; int meta; int save; int result; - alloca_used += sizeof init_names_buf; - - init_names->next = NULL; - init_names->count = ((sizeof init_names_buf - - offsetof (struct globnames, name)) - / sizeof init_names->name[0]); + globnames_array_init (&globnames); meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE)); if (meta == GLOBPAT_NONE && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) @@ -1294,34 +1297,10 @@ glob_in_dir (const char *pattern, const char *directory, int flags, if (fnmatch (pattern, d.name, fnm_flags) == 0) { - if (cur == names->count) - { - struct globnames *newnames; - size_t count = names->count * 2; - size_t nameoff = offsetof (struct globnames, name); - size_t size = FLEXSIZEOF (struct globnames, name, - count * sizeof (char *)); - if ((SIZE_MAX - nameoff) / 2 / sizeof (char *) - < names->count) - goto memory_error; - if (glob_use_alloca (alloca_used, size)) - newnames = names_alloca - = alloca_account (size, alloca_used); - else if ((newnames = malloc (size)) - == NULL) - goto memory_error; - newnames->count = count; - newnames->next = names; - names = newnames; - cur = 0; - } - names->name[cur] = strdup (d.name); - if (names->name[cur] == NULL) - goto memory_error; - ++cur; - ++nfound; - if (SIZE_MAX - pglob->gl_offs <= nfound) + globnames_array_add (&globnames, strdup (d.name)); + if (globnames_array_has_failed (&globnames)) goto memory_error; + nfound++; } } } @@ -1331,10 +1310,13 @@ glob_in_dir (const char *pattern, const char *directory, int flags, { size_t len = strlen (pattern); nfound = 1; - names->name[cur] = malloc (len + 1); - if (names->name[cur] == NULL) + char *newp = malloc (len + 1); + if (newp == NULL) + goto memory_error; + *((char *) mempcpy (newp, pattern, len)) = '\0'; + globnames_array_add (&globnames, newp); + if (globnames_array_has_failed (&globnames)) goto memory_error; - *((char *) mempcpy (names->name[cur++], pattern, len)) = '\0'; } result = GLOB_NOMATCH; @@ -1355,59 +1337,24 @@ glob_in_dir (const char *pattern, const char *directory, int flags, if (new_gl_pathv == NULL) { memory_error: - while (1) - { - struct globnames *old = names; - for (size_t i = 0; i < cur; ++i) - free (names->name[i]); - names = names->next; - /* NB: we will not leak memory here if we exit without - freeing the current block assigned to OLD. At least - the very first block is always allocated on the stack - and this is the block assigned to OLD here. */ - if (names == NULL) - { - assert (old == init_names); - break; - } - cur = names->count; - if (old == names_alloca) - names_alloca = names; - else - free (old); - } + globnames_array_free (&globnames); result = GLOB_NOSPACE; } else { - while (1) + struct globnames_result ret = { .names = 0, .length = -1 }; + if (!globnames_array_finalize (&globnames, &ret)) + result = GLOB_NOSPACE; + else { - struct globnames *old = names; - for (size_t i = 0; i < cur; ++i) + for (size_t i = 0; i < ret.length; ++i) new_gl_pathv[pglob->gl_offs + pglob->gl_pathc++] - = names->name[i]; - names = names->next; - /* NB: we will not leak memory here if we exit without - freeing the current block assigned to OLD. At least - the very first block is always allocated on the stack - and this is the block assigned to OLD here. */ - if (names == NULL) - { - assert (old == init_names); - break; - } - cur = names->count; - if (old == names_alloca) - names_alloca = names; - else - free (old); + = ret.names[i]; + pglob->gl_pathv = new_gl_pathv; + pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + pglob->gl_flags = flags; } - - pglob->gl_pathv = new_gl_pathv; - - pglob->gl_pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; - - pglob->gl_flags = flags; + free (ret.names); } } From patchwork Mon Feb 5 13:27:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869276 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89970-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="DwMoq6t1"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpMQ6N7bz9t3J for ; Tue, 6 Feb 2018 00:28:50 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=T1i0zbBkPCaAiHi71j2ReWAWLMgsYuj BajP9/zJtgXGbHwvrBkLRU57ft4qsIu9jsWx6Ni3O33ZcuRuV5IYCJxNn2XK9Jx/ dgbxQ3Hneezz1GXdR2osvwvqQDeJsdpPyf6hSq8TfN21QItUq3/oFS5QwPtzFIf9 ubZwLaR3oaA4= 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:subject:date:message-id:in-reply-to :references; s=default; bh=S4GZrd7PYrygxIkJad3slOchMDk=; b=DwMoq 6t1YCVkos5mG9dUN60dbohrjpn5hv/VifHI8PT9ccAkaypkeGS9YFdXEQEpwZfYl ylOEDTZtpBglC9kbOe8HYhyibN100hbUQaggRajSB1PDWX4mPX0NKoWodJZawKMD LhmTVV/ZKvqq//oaNUxG4yapxfTEI5JOZSLKgc= Received: (qmail 33172 invoked by alias); 5 Feb 2018 13:27:55 -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 32998 invoked by uid 89); 5 Feb 2018 13:27:54 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL, 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-qt0-f195.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:subject:date:message-id:in-reply-to :references; bh=PXCCHChDoVPOP8u0wH8xaEmB/sEpbx2BgABOmp9YnDc=; b=RtpKZpqRCAubL+wR9drjPv8ve8f70eqKNPJv0NGmZJqP0G/a5iys+XvyB1d04WCWsE /3wHCwp6Lu7URW4wIdgLceZ/FLtOU9tDSL3OK0d88dvEveLMbVp1k0n31zfRa1iUFAPo MurT16tmbUKh/q00s9AVMwjTanaohCtJOUGuN52oFhz6LAMYybIUHUHnCgCTl4+GBySg oSNNKjyoUcInk0bKPkTj5LbuplKyl1SVrvM/9sYYkJwjr6XfHd9L+qPb1zZTWUS7i6ev zMN92OEczFVHamEl+98pCwxCKNF8kZssv8dXe6CRXWFWN7tmcJ+Yy+1cSqkzKVeBJ8WC 02Eg== X-Gm-Message-State: AKwxytfA+ZysjOOn0TAW86FHPH3Rukae39YrCvXevXkjwfv4xEYXD0Ku T5jAqhAhM5/ZnbqtXlRBAxUI3+zuwzQ= X-Google-Smtp-Source: AH8x227x0oWYQE/iodLObHx6esaRgQ1f+isklc3nuB3EKj0qFZJcUd13a7Cvl5sgwsq7IcoQ8ZLkbg== X-Received: by 10.237.55.233 with SMTP id j96mr80327182qtb.192.1517837269962; Mon, 05 Feb 2018 05:27:49 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 06/12] posix: Remove alloca usage on glob user_name Date: Mon, 5 Feb 2018 11:27:28 -0200 Message-Id: <1517837254-19399-7-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> This patch uses dynarray at glob internal user name manipulation for GLOB_TILDE. It simplifies it and removes all the boilerplate buffer managements required. It also removes the glob_use_alloca, since it is not used anymore. Checked on x86_64-linux-gnu. * posix/glob.c (size_add_wrapv, glob_use_alloca): Remove. (__glob): Use char_array for user name. Signed-off-by: Adhemerval Zanella --- ChangeLog | 3 +++ posix/glob.c | 86 ++++++++++++++++++------------------------------------------ 2 files changed, 29 insertions(+), 60 deletions(-) diff --git a/posix/glob.c b/posix/glob.c index 2632e93..e914748 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -32,13 +32,13 @@ #ifndef WINDOWS32 # include +# include #endif #include #include #include #include -#include #ifdef _LIBC # undef strdup @@ -205,29 +205,6 @@ glob_lstat (glob_t *pglob, int flags, const char *fullname) : LSTAT64 (fullname, &ust.st64)); } -/* 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 bool -size_add_wrapv (size_t a, size_t b, size_t *r) -{ -#if 5 <= __GNUC__ && !defined __ICC - return __builtin_add_overflow (a, b, r); -#else - *r = a + b; - return *r < a; -#endif -} - -static bool -glob_use_alloca (size_t alloca_used, size_t len) -{ - size_t size; - return (!size_add_wrapv (alloca_used, len, &size) - && __libc_use_alloca (size)); -} - static int glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), glob_t *pglob, size_t alloca_used); @@ -713,11 +690,10 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), else { #ifndef WINDOWS32 - char *dirnamestr = char_array_at (&dirname, 0); - char *end_name = strchr (dirnamestr, '/'); - char *user_name; - int malloc_user_name = 0; - char *unescape = NULL; + const char *dirnamestr = char_array_str (&dirname); + const char *end_name = strchr (dirnamestr, '/'); + struct char_array user_name; + const char *unescape = NULL; if (!(flags & GLOB_NOESCAPE)) { @@ -731,27 +707,19 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), unescape = memchr (dirnamestr, '\\', end_name - dirnamestr); } if (end_name == NULL) - user_name = dirnamestr + 1; + { + if (!char_array_init_str (&user_name, dirnamestr + 1)) + goto err_nospace; + } else { - char *newp; - if (glob_use_alloca (alloca_used, end_name - dirnamestr)) - newp = alloca_account (end_name - dirnamestr, alloca_used); - else - { - newp = malloc (end_name - dirnamestr); - if (newp == NULL) - { - retval = GLOB_NOSPACE; - goto out; - } - malloc_user_name = 1; - } if (unescape != NULL) { - char *p = mempcpy (newp, dirnamestr + 1, - unescape - dirnamestr - 1); - char *q = unescape; + ptrdiff_t name_len = unescape - dirnamestr - 1; + if (!char_array_init_str_size (&user_name, dirnamestr + 1, + name_len)) + goto err_nospace; + const char *q = unescape; while (q != end_name) { if (*q == '\\') @@ -762,20 +730,21 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), but "~fo\\o\\/" unescape to user_name "foo". */ if (filename == NULL) - *p++ = '\\'; + char_array_append_char (&user_name, '\\'); break; } ++q; } - *p++ = *q++; + char_array_append_char (&user_name, *q++); } - *p = '\0'; } else - *((char *) mempcpy (newp, dirnamestr + 1, - end_name - dirnamestr - 1)) - = '\0'; - user_name = newp; + { + ptrdiff_t name_len = end_name - dirnamestr - 1; + if (!char_array_init_str_size (&user_name, dirnamestr + 1, + name_len)) + goto err_nospace; + } } /* Look up specific user's home directory. */ @@ -787,7 +756,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), # if defined HAVE_GETPWNAM_R || defined _LIBC struct passwd pwbuf; - while (getpwnam_r (user_name, &pwbuf, + while (getpwnam_r (char_array_str (&user_name), &pwbuf, pwtmpbuf.data, pwtmpbuf.length, &p) == ERANGE) { @@ -798,11 +767,10 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), } } # else - p = getpwnam (user_name); + p = getpwnam (char_array_str (&user_name)); # endif - if (__glibc_unlikely (malloc_user_name)) - free (user_name); + char_array_free (&user_name); /* If we found a home directory use this. */ if (p != NULL) @@ -1025,9 +993,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (meta & GLOBPAT_BACKSLASH) { char *p = strchr (char_array_str (&dirname), '\\'), *q; - /* We need to unescape the dirname string. It is certainly - allocated by alloca, as otherwise filename would be NULL - or dirname wouldn't contain backslashes. */ + /* We need to unescape the dirname string. */ q = p; do { From patchwork Mon Feb 5 13:27:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869278 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89971-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="erZ9nYLz"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpMg5yMCz9t42 for ; Tue, 6 Feb 2018 00:29:00 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=Y7UchqOVLpv5FBVox8Z0srb5FcEuZ6m 8uKPa2xf42KqGIx1cr349E1714joJps6VNueciHpVuham6tAoXqjaZIk+MA0ab+q rXFd+riOO3dI2yBsdJVbt9zeklgDHJJNOyb8wNVIXy1FcC4USJwlrUoBvlkGM/I8 mhUBZGhIHN8E= 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:subject:date:message-id:in-reply-to :references; s=default; bh=FALKffu/dfL2aQTX9ialG7HsT9I=; b=erZ9n YLzihILB7Q4awiU0WG5WjDnxkZzq2FqOpQQVBJL/Xpynw5QzBpN0TiDMPykg1O+Z BUrkCIlMrX5QFRHa3lAHp5gWL8RrCMIlirkh0+lh8/XdPUiqCKizz+8ceqWM2Rb5 4iXaUVmyOy34lzcOL5NfoXEBikl6F+4gDADyFM= Received: (qmail 33276 invoked by alias); 5 Feb 2018 13:27:55 -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 33164 invoked by uid 89); 5 Feb 2018 13:27:55 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.8 required=5.0 tests=AWL, 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-qk0-f196.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:subject:date:message-id:in-reply-to :references; bh=5XzsduIWwk1ccqp3emkwuvZfL9iPTQxAUihFNwbyzPA=; b=E5ot0+hMG+H4V7L5LAo96kvWfWYQ23ThW+aNMlVZz0NHEIJPGEASLizCH5PSGsKsGt 32MsQ62xd53tkrzT002EReNHMOJ70LkiMfYJO1dnHg0k7CjaMR04e8XIp2UpaYROtK6V 9Vq9Pc5PNxmNRGdRjlnkdJEQTz/9L+3baxL8hpIfw8OL0flwriH5FU3E7uQLc+QR0Sr3 5QP73VCMR7atmFpGtPzEApjdP0tfsKeut6rL62BDLOFQuPa3LKhbM9jlOd9WToijvRgO 2JfmhYL+YkrYtdBnB45tFmfS4v4+d6SHFB6kphQ7a/lo9aRlbZFtG/plsx/8Cl3brgKI hm1A== X-Gm-Message-State: AKwxytdBjNMjYWPWkxO+wXvBUX1ftuZd68XkFIKQxaXtav5qcQKQOSHM l0l7LxqGnIAqyXyOzTmY63WDQh2UMlY= X-Google-Smtp-Source: AH8x226AZca15qdrjbKsc2cExV9hdQB52jbIMc8Nx+3klzOtGr9e6yx1PExauVdRkESeiGnp9al1EA== X-Received: by 10.55.91.5 with SMTP id p5mr46354407qkb.32.1517837271392; Mon, 05 Feb 2018 05:27:51 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 07/12] posix: Use char_array for home_dir in glob Date: Mon, 5 Feb 2018 11:27:29 -0200 Message-Id: <1517837254-19399-8-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> This patch uses dynarray at glob internal home directory ame manipulation for GLOB_TILDE. It simplifies it and removes all the boilerplate buffer managements required. Checked x86_64-linux-gnu. * posix/glob.c (__glob): Use char_array for home directory. Signed-off-by: Adhemerval Zanella --- ChangeLog | 2 ++ posix/glob.c | 66 ++++++++++++++++++++++++++++++++++++------------------------ 2 files changed, 42 insertions(+), 26 deletions(-) diff --git a/posix/glob.c b/posix/glob.c index e914748..a78718d 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -596,9 +596,14 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), || char_array_pos (&dirname, 2) == '/'))) { /* Look up home directory. */ - char *home_dir = getenv ("HOME"); - int malloc_home_dir = 0; - if (home_dir == NULL || home_dir[0] == '\0') + struct char_array home_dir; + + const char *home_env = getenv ("HOME"); + home_env = home_env == NULL ? "" : home_env; + if (!char_array_init_str (&home_dir, home_env)) + goto err_nospace; + + if (char_array_is_empty (&home_dir)) { #ifdef WINDOWS32 /* Windows NT defines HOMEDRIVE and HOMEPATH. But give @@ -608,16 +613,21 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (home_drive != NULL && home_path != NULL) { - size_t home_drive_len = strlen (home_drive); - size_t home_path_len = strlen (home_path); - char *mem = alloca (home_drive_len + home_path_len + 1); - - memcpy (mem, home_drive, home_drive_len); - memcpy (mem + home_drive_len, home_path, home_path_len + 1); - home_dir = mem; + if (!char_array_set_str (&home_dir, home_drive) + || !char_array_append_str (&home_dir, home_path)) + { + char_array_free (&home_dir); + goto err_nospace; + } } else - home_dir = "c:/users/default"; /* poor default */ + { + if (!char_array_set_str (&home_dir, "c:/users/default")) + { + char_array_free (&home_dir); + goto err_nospace; + } + } #else int err; struct passwd *p; @@ -646,44 +656,48 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (!scratch_buffer_grow (&s)) goto err_nospace; } - if (err == 0) - { - home_dir = strdup (p->pw_dir); - malloc_home_dir = 1; - } + bool e = (err == 0 && char_array_set_str (&home_dir, p->pw_dir)); scratch_buffer_free (&s); - if (err == 0 && home_dir == NULL) + if (e == false) goto err_nospace; #endif /* WINDOWS32 */ } - if (home_dir == NULL || home_dir[0] == '\0') + if (char_array_is_empty (&home_dir)) { - if (__glibc_unlikely (malloc_home_dir)) - free (home_dir); if (flags & GLOB_TILDE_CHECK) { + char_array_free (&home_dir); retval = GLOB_NOMATCH; goto out; } else { - home_dir = (char *) "~"; /* No luck. */ - malloc_home_dir = 0; + if (!char_array_set_str (&home_dir, "~")) + { + char_array_free (&home_dir); + goto err_nospace; + } } } /* Now construct the full directory. */ + bool e = true; if (char_array_pos (&dirname, 1) == '\0') { - if (!char_array_set_str (&dirname, home_dir)) - goto err_nospace; + e = char_array_set_str (&dirname, char_array_str (&home_dir)); dirlen = char_array_size (&dirname) - 1; } else { /* Replaces '~' by the obtained HOME dir. */ char_array_erase (&dirname, 0); - if (!char_array_prepend_str (&dirname, home_dir)) - goto err_nospace; + e = char_array_prepend_str (&dirname, + char_array_str (&home_dir)); + } + if (e == false) + { + char_array_free (&dirname); + char_array_free (&home_dir); + goto err_nospace; } dirname_modified = true; } From patchwork Mon Feb 5 13:27:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869277 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89972-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="c1E/wgIA"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpMn75f2z9t61 for ; Tue, 6 Feb 2018 00:29:09 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=w1SWzeJtuDkk1X8208nTvp6HLqF60Ro B1x84KEC2qGNFDaOm7+Z0/eK360gIwc0P8XpB5Od/VrCLnjgL1F5UDVlLebEkfkA mogcNd2+4iBiEEkL3BpBeezt+XN2FQJ39L54xgJ7jQ5f0jCWPTr7WHdBSNnI+GtC GdqHynN99Sm8= 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:subject:date:message-id:in-reply-to :references; s=default; bh=oxyXbVmL+iymcqZfy8R2bFWJmO4=; b=c1E/w gIAZ3JcB6gTQWmXRCO7/WQ8LvwVJgqAdTboB5wfPlEWrRtfZkK6BHerUhhKrppbz hGz/iWYaFcNVywVIyzGt/FqDOrKu+BMuJdSN4v2qBzTZtmlPWHa6j5J7Jfczp3cT 0RHxgDLs/3GD44aiDBXt83SONdQ/06LSnNrk/E= Received: (qmail 33522 invoked by alias); 5 Feb 2018 13:27:57 -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 33403 invoked by uid 89); 5 Feb 2018 13:27:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.8 required=5.0 tests=AWL, 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=11917 X-HELO: mail-qt0-f195.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:subject:date:message-id:in-reply-to :references; bh=lcS1AVChHbUkNIWtpnKyeCRZQIZa+rM/3AlO26yW3OM=; b=IsK3dbC/JigoK44cannhNv7ohr0RQ6xEAWy/Vo1PYUKksiKdtXiCZfiq5VsnK9zvUD iqR3ns52q9UseQfNjVzIyLQOBeBikIh6oFHFEKlnswWCLWKNkmPJ6PfXxNsunnDhrJrl vgfVeRIMO811cRqyWPWeTpR00kvR8tmg5ZaZcxzkacmuryWLSMkrUlHTDaoe7Rr85UH7 ixYjX0+KTOXRL2ec5Vi4HlswJ5Z2r9PQSOs03SW3bal2SeHkrz8N2K3bxYCy1x79L4Jg B5QzUkaqsmH0Vh7jU0V1peNiS0pEqnyKWSf8wtdQ0MKWvwlyCu17K16BpV5L9wDuuNV5 Gu4A== X-Gm-Message-State: APf1xPDdw6D/2272+CmI2lkjrDqFaC85k/GZSdl89MMB9EEpFO5hApsm ia/ezJweeehIPJN+qYKBV0gLjW8SRh8= X-Google-Smtp-Source: AH8x22644kHyLqcDvp1JQD98V/NKRc9FEKGlRbvdFxX/01UvfgllSqT6bWu0CLqCzpk3RUPQSMxjlA== X-Received: by 10.200.36.37 with SMTP id c34mr1708233qtc.253.1517837272681; Mon, 05 Feb 2018 05:27:52 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 08/12] posix: Remove all alloca usage in glob Date: Mon, 5 Feb 2018 11:27:30 -0200 Message-Id: <1517837254-19399-9-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> With alloca usage removal from glob this patch wraps it up by removing all the alloca defines and macros usage. Checked on x86_64-linux-gnu. * posix/glob.c (glob_in_dir, glob): Remove alloca_used argument. Signed-off-by: Adhemerval Zanella --- ChangeLog | 2 ++ posix/glob.c | 25 ++++++++----------------- 2 files changed, 10 insertions(+), 17 deletions(-) diff --git a/posix/glob.c b/posix/glob.c index a78718d..118fcf5 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -32,7 +32,6 @@ #ifndef WINDOWS32 # include -# include #endif #include @@ -65,9 +64,6 @@ # define __stat64(fname, buf) stat (fname, buf) # define __fxstatat64(_, d, f, st, flag) fstatat (d, f, st, flag) # define struct_stat64 struct stat -# ifndef __MVS__ -# define __alloca alloca -# endif # define __readdir readdir # define COMPILE_GLOB64 #endif /* _LIBC */ @@ -174,12 +170,6 @@ convert_dirent64 (const struct dirent64 *source) # ifdef GNULIB_defined_closedir # undef closedir # endif - -/* Just use malloc. */ -# define __libc_use_alloca(n) false -# define alloca_account(len, avar) ((void) (len), (void) (avar), (void *) 0) -# define extend_alloca_account(buf, len, newlen, avar) \ - ((void) (buf), (void) (len), (void) (newlen), (void) (avar), (void *) 0) #endif static int @@ -207,7 +197,7 @@ glob_lstat (glob_t *pglob, int flags, const char *fullname) static int glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), - glob_t *pglob, size_t alloca_used); + glob_t *pglob); static int prefix_array (const char *prefix, char **array, size_t n) __THROWNL; static int collated_compare (const void *, const void *) __THROWNL; @@ -273,7 +263,6 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), bool dirname_modified; glob_t dirs; int retval = 0; - size_t alloca_used = 0; struct char_array dirname; if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0) @@ -520,11 +509,13 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), char *drive_spec; ++dirlen; - drive_spec = __alloca (dirlen + 1); + drive_spec = malloc (dirlen + 1); *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0'; /* For now, disallow wildcards in the drive spec, to prevent infinite recursion in glob. */ - if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE))) + int r = __glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)); + free (drive_spec); + if (r != 0) { retval = GLOB_NOMATCH; goto out; @@ -921,7 +912,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), status = glob_in_dir (filename, dirs.gl_pathv[i], ((flags | GLOB_APPEND) & ~(GLOB_NOCHECK | GLOB_NOMAGIC)), - errfunc, pglob, alloca_used); + errfunc, pglob); if (status == GLOB_NOMATCH) /* No matches in this directory. Try the next. */ continue; @@ -1026,7 +1017,7 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), if (dirname_modified) flags &= ~(GLOB_NOCHECK | GLOB_NOMAGIC); status = glob_in_dir (filename, char_array_str (&dirname), flags, - errfunc, pglob, alloca_used); + errfunc, pglob); if (status != 0) { if (status == GLOB_NOMATCH && flags != orig_flags @@ -1191,7 +1182,7 @@ struct globnames_result static int glob_in_dir (const char *pattern, const char *directory, int flags, int (*errfunc) (const char *, int), - glob_t *pglob, size_t alloca_used) + glob_t *pglob) { void *stream = NULL; struct globnames_array globnames; From patchwork Mon Feb 5 13:27:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869279 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89973-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="p58QSVjM"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpMy0hQfz9t3p for ; Tue, 6 Feb 2018 00:29:17 +1100 (AEDT) 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=c2bjLKEuwvp3pPXWc1PbqiarwT5ePOK clbYpk20qPkPsGhAMMULAwsXwpPLnUP7ZgOdKRN0TsptRyxN7UvGvGYlTmWrIeU2 fjUtcEo+qZlgk9Hns01TZkM6HYGyqD/3xQE8gxbBAnAAZSt9JgEK+6qB4udGxWtq 9Z/5f9iRFIjc= 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=GD0ULpkQL0RpLE7rXZW4t9tzI4c=; b=p58QS VjMiPoqv7K1CHcwLwTMeaxBYcrXjf/z0MPK3cy7X2OZzFh8SR9waokNMAtTS8QEG GWZ6wATaiq+vSBLQb1Ts08BxlyQaAN3s9GRirWTNpRt6lyHmzUOuow3xzHyZg3eq m6zxmgBRFLy/TmFBg4cvr2OZ5A109kKa+84+AM= Received: (qmail 33718 invoked by alias); 5 Feb 2018 13:27:58 -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 33567 invoked by uid 89); 5 Feb 2018 13:27:57 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.4 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mail-qt0-f182.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=pX1HWCiM7nk7eiqTgZ9r3GFmkrFlV+di1l00s9rLzk0=; b=hvOvB/jVhpmWzYLhWJSyIP6bHMtuQfuPvzYP8/4VAgpGHrezzSmzKWeXbdQ7G5Say8 IfQS/4sj0B4p00XubAT3kk9TS19LIxeoal1HP+2+DEmsWvQ6RT3VB8gRG+DR2bySlBnm PD8DooBuFd4SexYH/87jjl3qKpr6useFctXL5s9/cTj0o/z++7Sro/ZH+SiCAOpPLUph pVR8ulKgRY55A5k0JVRau+044URJpnHRpgYB1OmfPxoAPky4JK3gNGrvJUY37eZcIRni xUreci5VLufKRuEhn6RWP3iPAQPC8YLheVapdI20Kc9tXXsx3AAOqChEAFvFsqwUeDcw XSuQ== X-Gm-Message-State: APf1xPD+aXIHJsNueQ0eOb8C4GqnGG8bSXGy+tV4BFcW2nYaKaXvBn6a NeCkfl3+h/aPoanG9oJ90K9EaP6tlrY= X-Google-Smtp-Source: AH8x226V+F5lUqEqX/s/j9L6aYE3SLOF7elCgWS9uCSzII99cpH54pXDvN6wM6wIPjH0k53tMYZd+A== X-Received: by 10.200.56.17 with SMTP id q17mr8373745qtb.313.1517837274126; Mon, 05 Feb 2018 05:27:54 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Cc: Florian Weimer Subject: [PATCH v2 09/12] getlogin_r: switch Linux variant to struct scratch_buffer Date: Mon, 5 Feb 2018 11:27:31 -0200 Message-Id: <1517837254-19399-10-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> From: Florian Weimer [BZ #18023] * sysdeps/unix/sysv/linux/getlogin_r.c (__getlogin_r_loginuid): Use scratch_buffer instead of extend_alloca. --- ChangeLog | 6 ++++++ sysdeps/unix/sysv/linux/getlogin_r.c | 34 +++++++++++++--------------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/sysdeps/unix/sysv/linux/getlogin_r.c b/sysdeps/unix/sysv/linux/getlogin_r.c index 84c51d0..73ea14c 100644 --- a/sysdeps/unix/sysv/linux/getlogin_r.c +++ b/sysdeps/unix/sysv/linux/getlogin_r.c @@ -18,6 +18,7 @@ #include #include #include +#include #define STATIC static static int getlogin_r_fd0 (char *name, size_t namesize); @@ -54,29 +55,22 @@ __getlogin_r_loginuid (char *name, size_t namesize) endp == uidbuf || *endp != '\0')) return -1; - size_t buflen = 1024; - char *buf = alloca (buflen); - bool use_malloc = false; struct passwd pwd; struct passwd *tpwd; int result = 0; int res; + struct scratch_buffer tmpbuf; + scratch_buffer_init (&tmpbuf); - while ((res = __getpwuid_r (uid, &pwd, buf, buflen, &tpwd)) == ERANGE) - if (__libc_use_alloca (2 * buflen)) - buf = extend_alloca (buf, buflen, 2 * buflen); - else - { - buflen *= 2; - char *newp = realloc (use_malloc ? buf : NULL, buflen); - if (newp == NULL) - { - result = ENOMEM; - goto out; - } - buf = newp; - use_malloc = true; - } + while ((res = __getpwuid_r (uid, &pwd, + tmpbuf.data, tmpbuf.length, &tpwd)) == ERANGE) + { + if (!scratch_buffer_grow (&tmpbuf)) + { + result = ENOMEM; + goto out; + } + } if (res != 0 || tpwd == NULL) { @@ -95,9 +89,7 @@ __getlogin_r_loginuid (char *name, size_t namesize) memcpy (name, pwd.pw_name, needed); out: - if (use_malloc) - free (buf); - + scratch_buffer_free (&tmpbuf); return result; } From patchwork Mon Feb 5 13:27:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89974-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="VJXuKzxQ"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpN63flWz9t2l for ; Tue, 6 Feb 2018 00:29:26 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=bbSOI5Di6PJR1Tb/vHViqlDWmIk5REu zH2tgd34Hvy5mz14FAV7dOpFNUwMaDfvW2vu6yeVULK/67ME1fTmY/a/jqZ0br1e Ndq5CD1VpdjXEBzB4gLeyG6D5crbMA/xMPmWwIcRPmgoKNK/Ks0u6unPjF9Jibgs K1prskNdO0QI= 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:subject:date:message-id:in-reply-to :references; s=default; bh=cXBJZNshAgZsd0pdO4vw8tbDZxs=; b=VJXuK zxQBlOCn4vIstvmB2e5kT44Gl7VyFZ53OrjDzfsDuyVKZnXg3HtWOZLqYKsPL++G q4CPoUA1+csL0cxV4TSQANmxkHfCrAcLoRrMEVDlRePm74PpoFVu8/UBbAzdM6QU hoTKpGvkacJB7xJAlZ7Fo0cfXc6vDxaEN6HyjQ= Received: (qmail 33993 invoked by alias); 5 Feb 2018 13:28:00 -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 33913 invoked by uid 89); 5 Feb 2018 13:27:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.8 required=5.0 tests=AWL, 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-qt0-f195.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:subject:date:message-id:in-reply-to :references; bh=pO5YmZXZCF3nCQcBtKV/l7o12KYqRoZQdn90q4+ckw4=; b=hFbWBEShaP6oEexarc/aPm+yXczzQSv4ag3S9MUYqiLJwaNmH7wkY7L2uQOMvYx3KY vgcF9g8+R9mSpwhR0CpiXWcbBgevkRVgvJovmwh5H1sevbyumCE2VmAG2AP2pPO06ZhJ yY1N6Up/lh1gfoDzO2OMYkUrbSoCrrDRBhTX61MvqCtwxxkKaQGc+xEoJtXP+0c48gg7 4qQ4LfcvajAhhZX+LfTSbayc/hz3RCwuLGptc2azQ69KZIiXItEwqAa71fWOSmvk/BYj bMMR5/PPwSpuG1J/pNrmIfxnk4i2MlJdEIxZ3fZ8D9b18Gcg+5ZTtO2OOC4EEmtUr5Eu kNgA== X-Gm-Message-State: APf1xPBucVDyILbwThFEkghRxV+xc9xZkSJ3pe0bS8umuIiypU+bx4cY BARz/WW/Ogx6FXj5U6wTdmR6Uqatpo8= X-Google-Smtp-Source: AH8x227ls9/i+UupsD4jjNFjd7FuQd3ADSsl8cVPy/4f289DQIPcseyN98DoMsgSaSHJDQq06WFDlA== X-Received: by 10.200.53.221 with SMTP id l29mr2621846qtb.273.1517837275322; Mon, 05 Feb 2018 05:27:55 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 10/12] posix: Replace alloca usage with scratch_buffer for fnmatch Date: Mon, 5 Feb 2018 11:27:32 -0200 Message-Id: <1517837254-19399-11-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> Checked on x86_64-linux-gnu. * posix/fnmatch.c (fnmatch): Use scratch_buffer instead of alloca. Signed-off-by: Adhemerval Zanella --- ChangeLog | 5 ++ posix/fnmatch.c | 140 ++++++++++---------------------------------------------- 2 files changed, 29 insertions(+), 116 deletions(-) diff --git a/posix/fnmatch.c b/posix/fnmatch.c index a9b7626..4be7327 100644 --- a/posix/fnmatch.c +++ b/posix/fnmatch.c @@ -34,11 +34,7 @@ # include #endif -#ifdef _LIBC -# include -#else -# define alloca_account(size., var) alloca (size) -#endif +#include /* For platform which support the ISO C amendement 1 functionality we support user defined character classes. */ @@ -315,128 +311,40 @@ is_char_class (const wchar_t *wcs) # include "fnmatch_loop.c" # endif - int fnmatch (const char *pattern, const char *string, int flags) { # if HANDLE_MULTIBYTE - if (__builtin_expect (MB_CUR_MAX, 1) != 1) + if (__glibc_unlikely (MB_CUR_MAX != 1)) { - mbstate_t ps; - size_t n; - const char *p; - wchar_t *wpattern_malloc = NULL; - wchar_t *wpattern; - wchar_t *wstring_malloc = NULL; - wchar_t *wstring; - size_t alloca_used = 0; + mbstate_t ps = { 0 }; - /* Convert the strings into wide characters. */ - memset (&ps, '\0', sizeof (ps)); - p = pattern; -#ifdef _LIBC - n = __strnlen (pattern, 1024); -#else - n = strlen (pattern); -#endif - if (__glibc_likely (n < 1024)) - { - wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t), - alloca_used); - n = mbsrtowcs (wpattern, &p, n + 1, &ps); - if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong. - XXX Do we have to set `errno' to something which mbsrtows hasn't - already done? */ - return -1; - if (p) - { - memset (&ps, '\0', sizeof (ps)); - goto prepare_wpattern; - } - } - else - { - prepare_wpattern: - n = mbsrtowcs (NULL, &pattern, 0, &ps); - if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong. - XXX Do we have to set `errno' to something which mbsrtows hasn't - already done? */ - return -1; - if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) - { - __set_errno (ENOMEM); - return -2; - } - wpattern_malloc = wpattern - = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t)); - assert (mbsinit (&ps)); - if (wpattern == NULL) - return -2; - (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps); - } + /* Calculate the size needed to convert the strings to wide + characters. */ + size_t patsize = mbsrtowcs (NULL, &pattern, 0, &ps) + 1; + size_t strsize = mbsrtowcs (NULL, &string, 0, &ps) + 1; + size_t totsize = patsize + strsize; - assert (mbsinit (&ps)); -#ifdef _LIBC - n = __strnlen (string, 1024); -#else - n = strlen (string); -#endif - p = string; - if (__glibc_likely (n < 1024)) - { - wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t), - alloca_used); - n = mbsrtowcs (wstring, &p, n + 1, &ps); - if (__glibc_unlikely (n == (size_t) -1)) - { - /* Something wrong. - XXX Do we have to set `errno' to something which - mbsrtows hasn't already done? */ - free_return: - free (wpattern_malloc); - return -1; - } - if (p) - { - memset (&ps, '\0', sizeof (ps)); - goto prepare_wstring; - } - } - else + struct scratch_buffer s; + scratch_buffer_init (&s); + if (!scratch_buffer_set_array_size (&s, totsize, sizeof (wchar_t))) { - prepare_wstring: - n = mbsrtowcs (NULL, &string, 0, &ps); - if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong. - XXX Do we have to set `errno' to something which mbsrtows hasn't - already done? */ - goto free_return; - if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) - { - free (wpattern_malloc); - __set_errno (ENOMEM); - return -2; - } - - wstring_malloc = wstring - = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t)); - if (wstring == NULL) - { - free (wpattern_malloc); - return -2; - } - assert (mbsinit (&ps)); - (void) mbsrtowcs (wstring, &string, n + 1, &ps); + scratch_buffer_free (&s); + errno = ENOMEM; + return -1; } - int res = internal_fnwmatch (wpattern, wstring, wstring + n, - flags & FNM_PERIOD, flags, NULL, - alloca_used); + wchar_t *wpattern = s.data; + wchar_t *wstring = wpattern + patsize; + + /* Convert the strings into wide characters. */ + mbsrtowcs (wpattern, &pattern, patsize, &ps); + mbsrtowcs (wstring, &string, strsize, &ps); + + int res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1, + flags & FNM_PERIOD, flags, NULL, 0); - free (wstring_malloc); - free (wpattern_malloc); + scratch_buffer_free (&s); return res; } From patchwork Mon Feb 5 13:27:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869281 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89976-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="K2DvYvpg"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpNS1bHFz9sRV for ; Tue, 6 Feb 2018 00:29:44 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=Zb1KfBpWcZnXInWcvaiK1XAN2fSIWPh F6+w1AdHz1earVfswolk+wFDkElvYD9smF+m3iBdCeMYGMdnLUV2X5snOberfFMJ mDe/tTR8Mm3vNsWIR8eUO9e1UAlDpQALWzZt/AK++9lSv7rqgxoo/kPOey2wfJ3b VlfBgwPdjC3E= 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:subject:date:message-id:in-reply-to :references; s=default; bh=Ms6x3Nc6TD1TppsaJrIRDDuIRNU=; b=K2DvY vpgzZgs+ShhAjvzrlOLS3mfx5Y0qtHJreHa+UNXE2Bw1uJHQAt3pnR7ghbp5IK7K hlMnYlrUy18vfBgTM+lPKGPngJluSgzqd4Zi171cDlWasFFnzhbracDWptHcZExg XZ6qbuHybOEqgFv2iSn3P56lL+x3YncDu3hVTY= Received: (qmail 34413 invoked by alias); 5 Feb 2018 13:28:02 -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 34253 invoked by uid 89); 5 Feb 2018 13:28:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=AWL, 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=9577, EXT, _at, 11607 X-HELO: mail-qt0-f194.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:subject:date:message-id:in-reply-to :references; bh=8Ng3SSnrFlKKnkbE4serckCACun5eVAFlc9iPT1MO3o=; b=aDljyw6dGdM9fMqflnKgGYWVBx2Z9j2vh8XbR41jb+u7WYQfAd0wm7INqpVwfG8mkY U5NNdC5QGTB1yFV44DVLD+K0zJCgozQjsmuVgmhSEwLdmJSGRI9NnbxIt5r/sPDgk1MC pSE+g4+Z61YCA1rOd54zEqmrzsosvfCHuEO+97IHAS0j5W63B3RUz+XsUE4FjkDyNx/G aQb3mtfnqPv1FJWjxBXxejjcwBBpgxc/62cI6epqBHefTSpzGXNd9xX/Ef6CYZrJ4ioS dgq6wG/BzsYATuI2PdBCC3hhMCDniMn04HcTR56ct3Vps/0g0VZzmoNP2b/z9eELjXbD W9eQ== X-Gm-Message-State: AKwxytddq6QxHxfMTHL44l2ZvEOq4XaIrY1zcwBk28xcJDqogNRwAzPt vs/IxCIvcze4K2yb/gaWA2Tjx0Za7nY= X-Google-Smtp-Source: AH8x226srJID46yLY9RNgIgBr/Jy2nFj62xpsXWlpH9T86YLQOAB6VDXl3IQYR9F+Qd5F9EE1StkIQ== X-Received: by 10.200.34.35 with SMTP id o32mr81179171qto.103.1517837276721; Mon, 05 Feb 2018 05:27:56 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 11/12] posix: Remove alloca usage for internal fnmatch implementation Date: Mon, 5 Feb 2018 11:27:33 -0200 Message-Id: <1517837254-19399-12-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> This patch replaces the internal fnmatch pattern list generation from a linked list using alloca to a dynamic array. Checked on x86_64-linux-gnu. * posix/fnmatch_loop.c (FCT, EXT): Remove alloca_used argument and use dynamic_array for pattern list. Signed-off-by: Adhemerval Zanella --- ChangeLog | 3 + posix/fnmatch.c | 4 +- posix/fnmatch_loop.c | 162 +++++++++++++++++++++++++-------------------------- 3 files changed, 86 insertions(+), 83 deletions(-) diff --git a/posix/fnmatch.c b/posix/fnmatch.c index 4be7327..9c2cff0 100644 --- a/posix/fnmatch.c +++ b/posix/fnmatch.c @@ -342,7 +342,7 @@ fnmatch (const char *pattern, const char *string, int flags) mbsrtowcs (wstring, &string, strsize, &ps); int res = internal_fnwmatch (wpattern, wstring, wstring + strsize - 1, - flags & FNM_PERIOD, flags, NULL, 0); + flags & FNM_PERIOD, flags, NULL); scratch_buffer_free (&s); @@ -351,7 +351,7 @@ fnmatch (const char *pattern, const char *string, int flags) # endif /* mbstate_t and mbsrtowcs or _LIBC. */ return internal_fnmatch (pattern, string, string + strlen (string), - flags & FNM_PERIOD, flags, NULL, 0); + flags & FNM_PERIOD, flags, NULL); } # ifdef _LIBC diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c index e298cac..eadb343 100644 --- a/posix/fnmatch_loop.c +++ b/posix/fnmatch_loop.c @@ -28,15 +28,14 @@ struct STRUCT it matches, nonzero if not. */ static int FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, int no_leading_period, int flags, - struct STRUCT *ends, size_t alloca_used); + struct STRUCT *ends); static int EXT (INT opt, const CHAR *pattern, const CHAR *string, - const CHAR *string_end, int no_leading_period, int flags, - size_t alloca_used); + const CHAR *string_end, int no_leading_period, int flags); static const CHAR *END (const CHAR *patternp); static int FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, - int no_leading_period, int flags, struct STRUCT *ends, size_t alloca_used) + int no_leading_period, int flags, struct STRUCT *ends) { const CHAR *p = pattern, *n = string; UCHAR c; @@ -61,7 +60,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') { int res = EXT (c, p, n, string_end, no_leading_period, - flags, alloca_used); + flags); if (res != -1) return res; } @@ -91,7 +90,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') { int res = EXT (c, p, n, string_end, no_leading_period, - flags, alloca_used); + flags); if (res != -1) return res; } @@ -180,7 +179,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, for (--p; n < endp; ++n, no_leading_period = 0) if (FCT (p, n, string_end, no_leading_period, flags2, - &end, alloca_used) == 0) + &end) == 0) goto found; } else if (c == L('/') && (flags & FNM_FILE_NAME)) @@ -189,7 +188,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, ++n; if (n < string_end && *n == L('/') && (FCT (p, n + 1, string_end, flags & FNM_PERIOD, flags, - NULL, alloca_used) == 0)) + NULL) == 0)) return 0; } else @@ -203,7 +202,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, for (--p; n < endp; ++n, no_leading_period = 0) if (FOLD ((UCHAR) *n) == c && (FCT (p, n, string_end, no_leading_period, flags2, - &end, alloca_used) == 0)) + &end) == 0)) { found: if (end.pattern == NULL) @@ -958,8 +957,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, case L('!'): if (__builtin_expect (flags & FNM_EXTMATCH, 0) && *p == '(') { - int res = EXT (c, p, n, string_end, no_leading_period, flags, - alloca_used); + int res = EXT (c, p, n, string_end, no_leading_period, flags); if (res != -1) return res; } @@ -1038,26 +1036,37 @@ END (const CHAR *pattern) return p + 1; } +#if WIDE_CHAR_VERSION +# define PATTERN_PREFIX pattern_list +#else +# define PATTERN_PREFIX wpattern_list +#endif + +#define PASTE(a,b) PASTE1(a,b) +#define PASTE1(a,b) a##b + +#define DYNARRAY_STRUCT PATTERN_PREFIX +#define DYNARRAY_ELEMENT_FREE(ptr) free (*ptr) +#define DYNARRAY_ELEMENT CHAR * +#define DYNARRAY_PREFIX PASTE(PATTERN_PREFIX,_) +#define DYNARRAY_INITIAL_SIZE 8 +#include static int EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, - int no_leading_period, int flags, size_t alloca_used) + int no_leading_period, int flags) { const CHAR *startp; int level; - struct patternlist - { - struct patternlist *next; - CHAR malloced; - CHAR str[0]; - } *list = NULL; - struct patternlist **lastp = &list; + struct PATTERN_PREFIX list; size_t pattern_len = STRLEN (pattern); - int any_malloced = 0; + size_t pattern_i = 0; const CHAR *p; const CHAR *rs; int retval = 0; + PASTE (PATTERN_PREFIX, _init) (&list); + /* Parse the pattern. Store the individual parts in the list. */ level = 0; for (startp = p = pattern + 1; level >= 0; ++p) @@ -1099,28 +1108,20 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, { /* This means we found the end of the pattern. */ #define NEW_PATTERN \ - struct patternlist *newp; \ - size_t slen = (opt == L('?') || opt == L('@') \ - ? pattern_len : (p - startp + 1)); \ - slen = sizeof (struct patternlist) + (slen * sizeof (CHAR)); \ - int malloced = ! __libc_use_alloca (alloca_used + slen); \ - if (__builtin_expect (malloced, 0)) \ - { \ - newp = malloc (slen); \ - if (newp == NULL) \ - { \ - retval = -2; \ - goto out; \ - } \ - any_malloced = 1; \ - } \ - else \ - newp = alloca_account (slen, alloca_used); \ - newp->next = NULL; \ - newp->malloced = malloced; \ - *((CHAR *) MEMPCPY (newp->str, startp, p - startp)) = L('\0'); \ - *lastp = newp; \ - lastp = &newp->next + size_t slen = (opt == L('?') || opt == L('@') \ + ? pattern_len : (p - startp + 1)); \ + CHAR *newp = malloc (slen * sizeof (CHAR)); \ + if (newp != NULL) \ + { \ + *((CHAR *) MEMPCPY (newp, startp, p - startp)) = L('\0'); \ + PASTE (PATTERN_PREFIX,_add) (&list, newp); \ + } \ + if (newp == NULL || PASTE (PATTERN_PREFIX, _has_failed) (&list)) \ + { \ + retval = -2; \ + goto out; \ + } \ + NEW_PATTERN; } } @@ -1132,27 +1133,26 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, startp = p + 1; } } - assert (list != NULL); assert (p[-1] == L(')')); #undef NEW_PATTERN switch (opt) { case L('*'): - if (FCT (p, string, string_end, no_leading_period, flags, NULL, - alloca_used) == 0) + if (FCT (p, string, string_end, no_leading_period, flags, NULL) == 0) goto success; /* FALLTHROUGH */ case L('+'): - do + for (; pattern_i < PASTE (PATTERN_PREFIX, _size)(&list); pattern_i++) { for (rs = string; rs <= string_end; ++rs) /* First match the prefix with the current pattern with the current pattern. */ - if (FCT (list->str, string, rs, no_leading_period, + if (FCT (*PASTE (PATTERN_PREFIX, _at) (&list, pattern_i), string, + rs, no_leading_period, flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD, - NULL, alloca_used) == 0 + NULL) == 0 /* This was successful. Now match the rest with the rest of the pattern. */ && (FCT (p, rs, string_end, @@ -1160,7 +1160,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, ? no_leading_period : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0, flags & FNM_FILE_NAME - ? flags : flags & ~FNM_PERIOD, NULL, alloca_used) == 0 + ? flags : flags & ~FNM_PERIOD, NULL) == 0 /* This didn't work. Try the whole pattern. */ || (rs != string && FCT (pattern - 1, rs, string_end, @@ -1169,36 +1169,34 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, : (rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0), flags & FNM_FILE_NAME - ? flags : flags & ~FNM_PERIOD, NULL, - alloca_used) == 0))) + ? flags : flags & ~FNM_PERIOD, NULL) == 0))) /* It worked. Signal success. */ goto success; } - while ((list = list->next) != NULL); /* None of the patterns lead to a match. */ retval = FNM_NOMATCH; break; case L('?'): - if (FCT (p, string, string_end, no_leading_period, flags, NULL, - alloca_used) == 0) + if (FCT (p, string, string_end, no_leading_period, flags, NULL) == 0) goto success; /* FALLTHROUGH */ case L('@'): - do - /* I cannot believe it but `strcat' is actually acceptable - here. Match the entire string with the prefix from the - pattern list and the rest of the pattern following the - pattern list. */ - if (FCT (STRCAT (list->str, p), string, string_end, - no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD, - NULL, alloca_used) == 0) - /* It worked. Signal success. */ - goto success; - while ((list = list->next) != NULL); + for (; pattern_i < PASTE (PATTERN_PREFIX, _size) (&list); pattern_i++) + { + /* I cannot believe it but `strcat' is actually acceptable + here. Match the entire string with the prefix from the + pattern list and the rest of the pattern following the + pattern list. */ + if (FCT (STRCAT (*PASTE (PATTERN_PREFIX, _at) (&list, pattern_i), p), + string, string_end, no_leading_period, + flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD, + NULL) == 0) + /* It worked. Signal success. */ + goto success; + } /* None of the patterns lead to a match. */ retval = FNM_NOMATCH; @@ -1207,22 +1205,27 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, case L('!'): for (rs = string; rs <= string_end; ++rs) { - struct patternlist *runp; + size_t runp_i; - for (runp = list; runp != NULL; runp = runp->next) - if (FCT (runp->str, string, rs, no_leading_period, - flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD, - NULL, alloca_used) == 0) + for (runp_i = pattern_i; + runp_i != PASTE (PATTERN_PREFIX, _size) (&list); + runp_i++) + { + if (FCT (*PASTE (PATTERN_PREFIX, _at) (&list, runp_i), string, rs, + no_leading_period, + flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD, + NULL) == 0) break; + } /* If none of the patterns matched see whether the rest does. */ - if (runp == NULL + if (runp_i == PASTE (PATTERN_PREFIX, _size) (&list) && (FCT (p, rs, string_end, rs == string ? no_leading_period : rs[-1] == '/' && NO_LEADING_PERIOD (flags) ? 1 : 0, flags & FNM_FILE_NAME ? flags : flags & ~FNM_PERIOD, - NULL, alloca_used) == 0)) + NULL) == 0)) /* This is successful. */ goto success; } @@ -1240,18 +1243,15 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end, success: out: - if (any_malloced) - while (list != NULL) - { - struct patternlist *old = list; - list = list->next; - if (old->malloced) - free (old); - } + PASTE (PATTERN_PREFIX, _free) (&list); return retval; } +#undef PATTERN_PREFIX +#undef PASTE +#undef PASTE1 + #undef FOLD #undef CHAR From patchwork Mon Feb 5 13:27:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 869282 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=sourceware.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=libc-alpha-return-89975-incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b="GonH9C+1"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zZpNH1ydlz9t61 for ; Tue, 6 Feb 2018 00:29:35 +1100 (AEDT) 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:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=aBJUEGSfj9ZDaWa+/Iz6fZDw23onxSi 1vGJ/rJe4L6OKLZsJ9+6xnbEa7cc9tGvPER69S3otSvHkuRncxAvYzqU/1l4QAeu 4BNJTnQIRUuOnsRP9Ij4jOSR19h02zspkciiofr00A9Evr6hn/b6BY/g6lRo+i6w 7iGuoXkyUgC4= 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:subject:date:message-id:in-reply-to :references; s=default; bh=Qqob+YS+yYISCtl/NU03WgfUZ/Y=; b=GonH9 C+1GWYTagjsFHYe1RJ5XZRFbSZw6VGC0oCr63NhJelmFrJB7kNExRI5XP578srho DsjsBNd0w44EqtqtmjBgNrlmkWvNrQH+v34Twjcj52J+lhW0rOdsnb9ERIsiHecu OQS0lQGWDT7Vm5i81b+A8hD/4iCIhdf7AQkshQ= Received: (qmail 34377 invoked by alias); 5 Feb 2018 13:28:02 -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 34232 invoked by uid 89); 5 Feb 2018 13:28:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.8 required=5.0 tests=AWL, 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=5257, consist X-HELO: mail-qt0-f195.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:subject:date:message-id:in-reply-to :references; bh=irZLf3c/ePGBZvl+NaJEsUNVXb3EC6chEqzsgu8FLoE=; b=sk0ffL7PuSL0RzUA3BoLbaTlvVf8XWps+KZZq2uQGd0U8vRrrmwxDvjj6hB/qbUbbd pZkZ05cb41ctb0a8PehRs6qgno5V8gPK2l/iSlW0SRFuEBIPLYWjB9PbV06UiOoljPqT Yo4OLfmgc0oowJBIBWXxszOmsVNUNPSCuwUQ4EhlDFIT+znFyjudQRxnO/GgCLp55Xm4 hPyCnTMkaXj8DT1gY01huCPWZn1fZZ8nRzVbZWpUDOnk81ITACFvEb/A5jZUg3Ty2WPK GnzA3WhVqHwsgH7FkpvK4quHaml9Eqp4n3cH430dhTmgKfSYzaVoLQAguHTqZgntuOG+ ruiQ== X-Gm-Message-State: AKwxytcNvSN0TbP0KEif7ghsbIdZq8Smyc3Nw6qoehSBmUR1iazC6FXQ YdrUW0SnlNoOT8BbxKUxCJDJunfHRu0= X-Google-Smtp-Source: AH8x225mu9kPF/HUu+FZAvsbyz0sTmCkVjplO+3kL3TpeL2wiKxth2ND31yBWajZI8XiCzrjqupU/A== X-Received: by 10.200.39.40 with SMTP id g37mr77817378qtg.169.1517837277962; Mon, 05 Feb 2018 05:27:57 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2 12/12] posix: Remove VLA usage for internal fnmatch implementation Date: Mon, 5 Feb 2018 11:27:34 -0200 Message-Id: <1517837254-19399-13-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> References: <1517837254-19399-1-git-send-email-adhemerval.zanella@linaro.org> Checked on x86_64-linux-gnu. * posix/fnmatch.c: Include char_array required files. * posix/fnmatch_loop.c (FCT): Replace VLA with char_array. Signed-off-by: Adhemerval Zanella --- ChangeLog | 3 +++ posix/fnmatch.c | 1 + posix/fnmatch_loop.c | 68 +++++++++++++++++++++++++--------------------------- 3 files changed, 36 insertions(+), 36 deletions(-) diff --git a/posix/fnmatch.c b/posix/fnmatch.c index 9c2cff0..b94c965 100644 --- a/posix/fnmatch.c +++ b/posix/fnmatch.c @@ -35,6 +35,7 @@ #endif #include +#include /* For platform which support the ISO C amendement 1 functionality we support user defined character classes. */ diff --git a/posix/fnmatch_loop.c b/posix/fnmatch_loop.c index eadb343..831e5ba 100644 --- a/posix/fnmatch_loop.c +++ b/posix/fnmatch_loop.c @@ -493,26 +493,20 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, { int32_t table_size; const int32_t *symb_table; -# if WIDE_CHAR_VERSION - char str[c1]; - unsigned int strcnt; -# else -# define str (startp + 1) -# endif + struct char_array str; + char_array_init_empty (&str); const unsigned char *extra; int32_t idx; int32_t elem; int32_t second; int32_t hash; -# if WIDE_CHAR_VERSION /* We have to convert the name to a single-byte string. This is possible since the names consist of ASCII characters and the internal representation is UCS4. */ - for (strcnt = 0; strcnt < c1; ++strcnt) - str[strcnt] = startp[1 + strcnt]; -#endif + for (size_t strcnt = 0; strcnt < c1; ++strcnt) + char_array_append_char (&str, startp[1 + strcnt]); table_size = _NL_CURRENT_WORD (LC_COLLATE, @@ -525,7 +519,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, _NL_COLLATE_SYMB_EXTRAMB); /* Locate the character in the hashing table. */ - hash = elem_hash (str, c1); + hash = elem_hash (char_array_str (&str), c1); idx = 0; elem = hash % table_size; @@ -539,7 +533,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (symb_table[2 * elem] == hash && (c1 == extra[symb_table[2 * elem + 1]]) - && memcmp (str, + && memcmp (char_array_str (&str), &extra[symb_table[2 * elem + 1] + 1], c1) == 0) @@ -580,14 +574,20 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, break; if ((int32_t) c1 == wextra[idx]) - goto matched; + { + char_array_free (&str); + goto matched; + } # else for (c1 = 0; c1 < extra[idx]; ++c1) if (n[c1] != extra[1 + c1]) break; if (c1 == extra[idx]) - goto matched; + { + char_array_free (&str); + goto matched; + } # endif } @@ -608,18 +608,21 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, { /* No valid character. Match it as a single byte. */ - if (!is_range && *n == str[0]) - goto matched; + char str0 = *char_array_at (&str, 0); + if (!is_range && *n == str0) + { + char_array_free (&str); + goto matched; + } - cold = str[0]; + cold = str0; c = *p++; } - else - return FNM_NOMATCH; + char_array_free (&str); + return FNM_NOMATCH; } } else -# undef str #endif { c = FOLD (c); @@ -711,26 +714,20 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, { int32_t table_size; const int32_t *symb_table; -# if WIDE_CHAR_VERSION - char str[c1]; - unsigned int strcnt; -# else -# define str (startp + 1) -# endif + struct char_array str; + char_array_init_empty (&str); const unsigned char *extra; int32_t idx; int32_t elem; int32_t second; int32_t hash; -# if WIDE_CHAR_VERSION /* We have to convert the name to a single-byte string. This is possible since the names consist of ASCII characters and the internal representation is UCS4. */ - for (strcnt = 0; strcnt < c1; ++strcnt) - str[strcnt] = startp[1 + strcnt]; -# endif + for (size_t strcnt = 0; strcnt < c1; ++strcnt) + char_array_append_char (&str, startp[1 + strcnt]); table_size = _NL_CURRENT_WORD (LC_COLLATE, @@ -744,7 +741,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, /* Locate the character in the hashing table. */ - hash = elem_hash (str, c1); + hash = elem_hash (char_array_str (&str), c1); idx = 0; elem = hash % table_size; @@ -758,7 +755,7 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, if (symb_table[2 * elem] == hash && (c1 == extra[symb_table[2 * elem + 1]]) - && memcmp (str, + && memcmp (char_array_str (&str), &extra[symb_table[2 * elem + 1] + 1], c1) == 0) { @@ -800,13 +797,12 @@ FCT (const CHAR *pattern, const CHAR *string, const CHAR *string_end, } else if (symb_table[2 * elem] != 0 && c1 == 1) { - cend = str[0]; + cend = *char_array_at (&str, 0); c = *p++; } - else - return FNM_NOMATCH; + char_array_free (&str); + return FNM_NOMATCH; } -# undef str } else {