From patchwork Tue Nov 21 13:55:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 119354 Delivered-To: patch@linaro.org Received: by 10.80.225.132 with SMTP id k4csp5124492edl; Tue, 21 Nov 2017 05:56:13 -0800 (PST) X-Google-Smtp-Source: AGs4zMajGPmD18guQSyEFbzhtBCKrAkRRxsn07qWTugPXmZ1DU9i2d+HifvW44J4FXO8cXoBcl3O X-Received: by 10.84.244.11 with SMTP id g11mr4200705pll.80.1511272572990; Tue, 21 Nov 2017 05:56:12 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511272572; cv=none; d=google.com; s=arc-20160816; b=cboByrsY94PFBDe6C64tp+qyAYnxg/zAN4AGX4Tp/iiqsuGZcndXlhJRQxP3r1efvA OGlqvRVZOJn4FV2AtHkObYgVKXSF6RqJWKs0KrstCwHWKknwoZVixj4Bhh3lCsVboXlU ooGy+AQz2ZKa6AUMFgeC97UOls9vjOqJNOSZf1ICoFRxHE5EmLW+1fXkxlFCJUOskDEv eNkXDCySmpAwdJ+251iTMl7P4E9eJyihpKodXXYwmEWZytm5jHj9wrHKzxUj6Y6ZtGhy M8rYcDpQ34osJhSvpO/VjHycfe0C3CittsyKm3Pinuyg/X/A7M7VQMWZfyhqYWpftTBU i4Ew== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=xKxNEEDy6bZcG7YdWj+iNH5DUJ4/UzQwxwYUFP56cLA=; b=dWieseAVKSpPJb1dUTmHkWLDmnnaPis3UUuEDSLNqOEDH+Dd/t/LLvPZaHNDyR+UAu m7XVP1vfLENXcrVR1WZOCV57l73FFK4bbyAM1pIPekeqHg198EHrk0ekL/osW3bo5tKT 5qnYB+Vj33iqDcO/eWSoFqFk6QBWVoJwO/LqiL339meDx7xvy2zfn0rv3q7QOGjnkzyP 3982MYUSkI5GcNuBcQGx6A9rMmSGYtT0lt2NunfFw19hV0bVBnYVSkfRK1X6Mh7ZV5Yq eqQUiefuXk9qmSkb3R4uNj7gQE/onfs8rkBgg/WR4mIMlfPUHnKlvlCCfTbeI3+Ab30V DeSw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=xyhU/vm1; spf=pass (google.com: domain of libc-alpha-return-87358-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87358-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id z19si7443534pff.152.2017.11.21.05.56.12 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Nov 2017 05:56:12 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-87358-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=xyhU/vm1; spf=pass (google.com: domain of libc-alpha-return-87358-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87358-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=RdA9RwqEWc3RfNKZHzXiWHaMo8ffno2 TPmrOj9KO2mwLQ03PgpjcIkdw8MQCr5vKXmc9qn+qIctA+ffcuAncWWmT7tEiJU1 qFfs65c+F5Lj61RtSeEMbaYYUmnvecMVxndOUqVdybtQkWNA1qrQ9Eq8D/hiZu9c FXZdndiuExQg= 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=I5T8aHHzWRZWXBAxlhVu33DvgQE=; b=xyhU/ vm1x6k9SN3A4MfFabbdZS15WXCC1rFbe7XotUBesKnPLa1mqYIXg6RCVFoeZ3k2z G/F7Tep8bN8g2L2qT6KW3YukMugfsRx2vFdspwol16WT+PzvnMQaX1A6HpB2+XRW YxgeHK4N8XrVF3pHaeF3EpxEzNGUoft0x8Xxx0= Received: (qmail 44286 invoked by alias); 21 Nov 2017 13:55:46 -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 44167 invoked by uid 89); 21 Nov 2017 13:55:46 -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, KAM_SHORT, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=USED, resize X-HELO: mail-qk0-f179.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=xKxNEEDy6bZcG7YdWj+iNH5DUJ4/UzQwxwYUFP56cLA=; b=Zf0HUiAjjeWl6sjwRrIRj9opz7q8aqgix3uaDmnJkLUSFTaWQUFFAr6hHty9MgSa66 e18NbVvvOrBofGQw4iy99O9GWYfZPoJI9PYYwl4foFw4RJRtbrhGeuw9eqOOvsmKt5S8 EZPkApF5ni36KhaeyVD8S18mN/3aVvJr1CAtAXr3CV4hYs6luUu6Y9kehpkxnMpv3MDU 7pxTECizh2wyVlpK0oDioM7GUe8d7RBx2RbJxODWtpU+HE0Ejswd4MW8HO+K61Ib3IaN oKhSoEzRwxakHnEE9OB78mFU5SPx77AFSI7Fk89Qh6Kg0OPoOjJM9Uk1R3ALqMNClkkp Y9ew== X-Gm-Message-State: AJaThX6dFqkpgEOOjGzndcUbOECgdXlT3dcRG+2zjVAN7gy/KM0c5zIR /fQ8ljQSuejCibjAz25LvkVuAgIz5S8= X-Received: by 10.55.234.20 with SMTP id t20mr26235589qkj.131.1511272538942; Tue, 21 Nov 2017 05:55:38 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 1/8] malloc: Add specialized dynarray for C strings Date: Tue, 21 Nov 2017 11:55:23 -0200 Message-Id: <1511272530-10936-2-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1511272530-10936-1-git-send-email-adhemerval.zanella@linaro.org> References: <1511272530-10936-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 | 279 +++++++++++++++++++++++++++++++++++++ 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, 580 insertions(+), 1 deletion(-) create mode 100644 malloc/char_array-impl.c create mode 100644 malloc/char_array-skeleton.c create mode 100644 malloc/char_array.h create mode 100644 malloc/dynarray_overflow_failure.c create mode 100644 malloc/tst-char_array.c -- 2.7.4 diff --git a/malloc/Makefile b/malloc/Makefile index 17936fc..8435e7f 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -49,6 +49,7 @@ tests-internal += \ tst-dynarray \ tst-dynarray-fail \ tst-dynarray-at-fail \ + tst-char_array ifneq (no,$(have-tunables)) tests += tst-malloc-usable-tunables @@ -61,7 +62,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 \ @@ -71,6 +72,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..5a56bbc --- /dev/null +++ b/malloc/char_array-impl.c @@ -0,0 +1,57 @@ +/* Specialized dynarray for C strings. Implementation file. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +void +__char_array_set_str_size (struct dynarray_header *header, const char *str, + size_t size) +{ + *((char *) mempcpy (header->array, str, size)) = '\0'; + header->used = size + 1; +} +libc_hidden_def (__char_array_set_str_size) + +void +__char_array_erase (struct dynarray_header *header, size_t pos) +{ + char *ppos = header->array + pos; + char *lpos = header->array + header->used; + ptrdiff_t size = lpos - ppos; + memmove (ppos, ppos + 1, size); + header->used--; +} +libc_hidden_def (__char_array_erase) + +void +__char_array_prepend_str_size (struct dynarray_header *header, + const char *str, size_t size, size_t used) +{ + memmove (header->array + size, header->array, used); + memcpy (header->array, str, size); +} +libc_hidden_def (__char_array_prepend_str_size) + +void +__char_array_replace_str_pos (struct dynarray_header *header, size_t pos, + const char *str, size_t len) +{ + char *start = header->array + pos; + *(char *) mempcpy (start, str, len) = '\0'; +} +libc_hidden_def (__char_array_replace_str_pos) diff --git a/malloc/char_array-skeleton.c b/malloc/char_array-skeleton.c new file mode 100644 index 0000000..00d3a30 --- /dev/null +++ b/malloc/char_array-skeleton.c @@ -0,0 +1,279 @@ +/* Specialized dynarray for C strings. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* This file provides a dynamic C string with an initial stack allocated + buffer. Since it is based on dynarray, it 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_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 (struct char_array *array) +{ + return char_array_begin (array); +} + +/* Return the character at position 'pos' from the char_array 'array'. */ +__attribute__ ((unused, nonnull (1))) +static char +char_array_pos (struct char_array *array, size_t pos) +{ + return *char_array_at (array, pos); +} + +/* Calculate the length of the string, excluding the terminating null. */ +__attribute__ ((unused, nonnull (1))) +static size_t +char_array_length (struct char_array *array) +{ + /* Exclude the final '\0'. */ + return array->dynarray_header.used - 1; +} + +/* Copy up 'size' bytes from string 'str' to char_array 'array'. A final + '\0' is appended in the char_array. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_set_str_size (struct char_array *array, const char *str, + size_t size) +{ + size_t newsize; + if (check_add_overflow_size_t (size, 1, &newsize)) + __libc_dynarray_overflow_failure (size, 1); + + if (!char_array_resize (array, newsize)) + return false; + + __char_array_set_str_size (&array->dynarray_abstract, str, size); + return true; +} + +/* Copy the contents of string 'str' to char_array 'array', including the + final '\0'. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_set_str (struct char_array *array, const char *str) +{ + return char_array_set_str_size (array, str, strlen (str)); +} + +/* Initialize the char_array 'array' and sets it to an empty string (""). */ +__attribute__ ((unused, nonnull (1))) +static bool +char_array_init_empty (struct char_array *array) +{ + char_array_init (array); + return char_array_set_str (array, ""); +} + +/* Initialize the char_array 'array' and copy the content of string 'str'. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_init_str (struct char_array *array, const char *str) +{ + char_array_init (array); + return char_array_set_str (array, str); +} + +/* Initialize the char_array 'array' and copy the content of string 'str' + up to 'size' characteres. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_init_str_size (struct char_array *array, const char *str, + size_t size) +{ + char_array_init (array); + return char_array_set_str_size (array, str, size); +} + +/* Return if the char_array contain any characteres. */ +__attribute__ ((unused, nonnull (1))) +static bool +char_array_is_empty (struct char_array *array) +{ + return *char_array_begin (array) == '\0'; +} + +/* Remove the byte at position 'pos' from char_array 'array'. The contents + are moved internally if the position is not at the end of the internal + buffer. */ +__attribute__ ((unused, nonnull (1))) +static bool +char_array_erase (struct char_array *array, size_t pos) +{ + if (pos >= array->dynarray_header.used - 1) + return false; + + __char_array_erase (&array->dynarray_abstract, pos); + return true; +} + +/* Resize the char_array 'array' to size 'count' maintaining the ending + '\0' byte. */ +__attribute__ ((unused, nonnull (1))) +static bool +char_array_crop (struct char_array *array, size_t size) +{ + if (size >= (array->dynarray_header.used - 1) + || !char_array_resize (array, size + 1)) + return false; + + array->dynarray_header.array[size] = '\0'; + return true; +} + +/* Prepend the contents of string 'str' to char_array 'array', including the + final '\0' byte. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_prepend_str (struct char_array *array, const char *str) +{ + size_t size = strlen (str); + /* Resizing the array might change its used elements and we need below + to correct copy the elements. */ + size_t used = array->dynarray_header.used; + + size_t newsize; + if (check_add_overflow_size_t (used, size, &newsize)) + __libc_dynarray_overflow_failure (used, size); + + /* Make room for the string and copy it. */ + if (!char_array_resize (array, newsize)) + return false; + __char_array_prepend_str_size (&array->dynarray_abstract, str, size, used); + return true; +} + +/* Append the contents of string 'str' to char_array 'array, including the + final '\0' byte. */ +__attribute__ ((unused, nonnull (1, 2))) +static bool +char_array_append_str (struct char_array *array, const char *str) +{ + size_t size = strlen (str); + /* Resizing the array might change its used elements and it used it below + to correct copy the elements. */ + size_t used = array->dynarray_header.used - 1; + + /* 'used' does account for final '\0', so there is no need to add + an extra element to calculate the final required size. */ + size_t newsize; + if (check_add_overflow_size_t (used + 1, size, &newsize)) + __libc_dynarray_overflow_failure (used + 1, size); + + if (!char_array_resize (array, newsize)) + return false; + + /* Start to append at '\0' up to string length and add a final '\0'. */ + *(char*) mempcpy (array->dynarray_header.array + used, str, size) = '\0'; + return true; +} + +/* 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..c696673 --- /dev/null +++ b/malloc/char_array.h @@ -0,0 +1,53 @@ +/* Specialized dynarray for C strings. Shared definitions. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _CHAR_ARRAY_H +#define _CHAR_ARRAY_H + +#include + +/* Internal funciton. Set the dynarray to the content of the string STR up + to SIZE bytes. The dynarray must be resized previously. */ +void __char_array_set_str_size (struct dynarray_header *, const char *str, + size_t size); + +/* Internal function. Remove the character at position POS from dynarray. + The position must be a valid one. */ +void __char_array_erase (struct dynarray_header *, size_t pos); + +/* Internal function. Prepend the content of string STR up to SIZE bytes to + dynarray by moving USED bytes forward. The dynarray must be resized + previously. */ +void __char_array_prepend_str_size (struct dynarray_header *, + const char *str, size_t size, + size_t used); + +/* Internal function. Replace the content of dynarray starting at position + POS with the content of string STR up to LEN bytes. The dynarray must + be resize previously and STR must contain at least LEN bytes. */ +void __char_array_replace_str_pos (struct dynarray_header *, size_t pos, + const char *str, size_t len); + +#ifndef _ISOMAC +libc_hidden_proto (__char_array_set_str_size) +libc_hidden_proto (__char_array_erase) +libc_hidden_proto (__char_array_prepend_str_size) +libc_hidden_proto (__char_array_replace_str_pos) +#endif + +#endif diff --git a/malloc/dynarray.h b/malloc/dynarray.h index 5888bcb..bb52b0f 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..14936b0 --- /dev/null +++ b/malloc/dynarray_overflow_failure.c @@ -0,0 +1,31 @@ +/* Report an dynamic array size overflow condition. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +void +__libc_dynarray_overflow_failure (size_t size, size_t incr) +{ + char buf[200]; + __snprintf (buf, sizeof (buf), "Fatal glibc error: " + "new size overflows (old %zu and increment %zu)\n", + size, incr); + __libc_fatal (buf); +} +libc_hidden_def (__libc_dynarray_overflow_failure) diff --git a/malloc/malloc-internal.h b/malloc/malloc-internal.h index a9c9c6a..3957ebb 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 5 <= __GNUC__ + return __builtin_add_overflow (a, b, r); +#else + *r = a + b; + return *r < a; +#endif +} + #endif /* _MALLOC_INTERNAL_H */ diff --git a/malloc/tst-char_array.c b/malloc/tst-char_array.c new file mode 100644 index 0000000..a3a99fb --- /dev/null +++ b/malloc/tst-char_array.c @@ -0,0 +1,112 @@ +/* Test for char_array. + Copyright (C) 2017 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +#include + +#include +#include +#include +#include +#include + +static int +do_test (void) +{ + mtrace (); + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_empty (&str) == true); + TEST_VERIFY_EXIT (char_array_length (&str) == 0); + TEST_VERIFY_EXIT (char_array_is_empty (&str) == true); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "") == 0); + char_array_free (&str); + } + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_str (&str, "testing")); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("testing")); + TEST_VERIFY_EXIT (char_array_pos (&str, 2) == 's'); + TEST_VERIFY_EXIT (char_array_is_empty (&str) == false); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "testing") == 0); + char_array_free (&str); + } + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_str_size (&str, "testing", 4)); + TEST_VERIFY_EXIT (char_array_length (&str) == 4); + TEST_VERIFY_EXIT (char_array_pos (&str, 2) == 's'); + TEST_VERIFY_EXIT (char_array_is_empty (&str) == false); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "test") == 0); + char_array_free (&str); + } + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_str (&str, "testing")); + TEST_VERIFY_EXIT (char_array_set_str (&str, "abcdef")); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "abcdef") == 0); + TEST_VERIFY_EXIT (char_array_set_str_size (&str, "abcdef", 4)); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "abcd") == 0); + char_array_free (&str); + } + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_str (&str, "testing")); + TEST_VERIFY_EXIT (char_array_erase (&str, 4) == true); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("testing") - 1); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "testng") == 0); + TEST_VERIFY_EXIT (char_array_erase (&str, char_array_length (&str)) + == false); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("testing") - 1); + TEST_VERIFY_EXIT (char_array_erase (&str, char_array_length (&str) - 1) + == true); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("testing") - 2); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "testn") == 0); + char_array_free (&str); + } + + { + struct char_array str; + TEST_VERIFY_EXIT (char_array_init_str (&str, "test")); + TEST_VERIFY_EXIT (char_array_prepend_str (&str, "123")); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "123test") == 0); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("123test")); + TEST_VERIFY_EXIT (char_array_append_str (&str, "456")); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "123test456") == 0); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("123test456")); + TEST_VERIFY_EXIT (char_array_replace_str_pos (&str, 7, "789", 3)); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "123test789") == 0); + TEST_VERIFY_EXIT (char_array_length (&str) == strlen ("123test789")); + TEST_VERIFY_EXIT (char_array_crop (&str, 7)); + TEST_VERIFY_EXIT (char_array_length (&str) == 7); + TEST_VERIFY_EXIT (strcmp (char_array_str (&str), "123test") == 0); + 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 Tue Nov 21 13:55:24 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 119356 Delivered-To: patch@linaro.org Received: by 10.80.225.132 with SMTP id k4csp5124817edl; Tue, 21 Nov 2017 05:56:31 -0800 (PST) X-Google-Smtp-Source: AGs4zMYNkSOyoRz4QOPrOnZ92ifCsvFUZJf17+i9jXRjSK9f9MS3IrXioIcb8zZ9cUT2Jv6VI4Ut X-Received: by 10.99.95.133 with SMTP id t127mr16965830pgb.368.1511272591043; Tue, 21 Nov 2017 05:56:31 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511272591; cv=none; d=google.com; s=arc-20160816; b=rFldM/fnKTgpGNSCNvOkivKoEvOj8TOdgSK3lYo1cQq+SEqkx9NP9dFhslnFlElE4g hPpI94AN9tvQ8RTto5I9t6HuavYpGtmv/N9DTR2V6VncMzQ3IEu5esEPCQjNXiCeyagv XysnBZBjZ3SN0vaZnEui8uuJw9KEOgSEOW084fKuNHcbNkZCj8IqT2Is3oxwjwW/WG8H 7G3HYuf0gTdpA6Vr9jTX1L0RRPTC7aiMbRXz8JEtCI7/Qp0rExb/85suvRMVHnWu7DSE 0kxf3xQoR2hlPJX9iOz4MvjvGpcP9XFEppGwj5j/VkVpe5sTO4DjDzm7bdSiiQsSXWUl 4+ZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=e3M99bh8PdxKe4J/u9m76Lg406TnBBpuz7mY/QGwLFU=; b=S5pc6hOM0TgrtmY4hHmV+YQYV2jjweNP+U673f3d9fq+XdOWWqqN9kT1zxieVelbl4 crgWJHAwSige+KZ2/32k9867WvDTh88uFCfZFLkxNYC5qTHpog7rMIEfQ26peXhJ9QcO 7juUZX1fHJJ8gLlUtwFQbRdo+2BeLB3sww2as0RQg3yzAgwE1ES3F+xWCn+Txh6n/JCM HWDJvcnJBgn7RnBYAEyb2IK53XFrYb7NRrZcgBxbhzffvcrHXc4Z0MQNFHm7VUWUHkXV YhAul+7lDC6IU/5c4n9zKNKa3unGT4akKwhtazcwdio1gcZiEbURznGuUGrNaWl5eOCx ieiQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=jZoKwNcm; spf=pass (google.com: domain of libc-alpha-return-87360-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87360-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id f34si10917611ple.337.2017.11.21.05.56.30 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Nov 2017 05:56:31 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-87360-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=jZoKwNcm; spf=pass (google.com: domain of libc-alpha-return-87360-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87360-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=mK4Ua/GwRl3zg8n05ImvbtSq8F4lEF0 lQNTVEa4Rk5kARmbBV2TZAqt08UcttM5hs0Kg+6dXIVF7vm37rWnfTsCxx2pfDkp ajcbcctDyxKV+n0GEx55Mownp0ZGrtEw/pb6yThuZGYue7AkNDf7tbJQGFVIL+XQ cX9FW2dTLnbc= 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=5a34/ZDHf9y/FoJj648ZXRZk9Ac=; b=jZoKw Ncmq2QBAikGSDDZ1+/heLdHvswk+PeElFyXuUNe9TLihnYPsFLiaxhTc0IAICLDw YXbOWcxqwJy+LpQTMydnboi8RzWKGR3/Rj2ayhPt3F3YOqDpMsXW9Lo4OxnXr+Wz 4dyGzaA7ZgLLZOxuyivTt6yMM+HfqJgvk+k5Ds= Received: (qmail 44392 invoked by alias); 21 Nov 2017 13:55:47 -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 44165 invoked by uid 89); 21 Nov 2017 13:55:46 -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, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=Stick, 9927, 11348 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=e3M99bh8PdxKe4J/u9m76Lg406TnBBpuz7mY/QGwLFU=; b=EhyyfCfPl8PYCmZOxE0l0GLk+vUKq27epbkAx7ujQ0IivuIdW6Xza7utEjZlPs5UJk nDcksD61baIy8+WH8D9NRRx1Lp0KnbOmXJDkr86k7o9+Bl0BsTkszQg/6+YV6l07w63a iSoLb48pPL+Io1Ut8QaZMY7kdQm3hxLEWLb4zjmFighImfuuS3Ix++TgsKjHoTSAkCwN sxmEMW/q8DwI9BCdawypAhpKZBmmXm8l6shyE4SPTekbvODdDh/e3kptzKxDfUj26jqC SYUcF3G5XhjU2SpPz+JpIiF0qN/ReMrCuhOag/83bl9JX5OdpPquWr5Y5xVvx+SZ9SVk fgzg== X-Gm-Message-State: AJaThX71rFpRyQXUzcl0y/LW0Emo6EaYF0IdcLDVN0i00++oJ2aKSpMY PbQoWiveobpMsjPRoFcuB8L9Zfp7R4Y= X-Received: by 10.55.8.4 with SMTP id 4mr6803771qki.249.1511272540472; Tue, 21 Nov 2017 05:55:40 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 2/8] posix: Use char_array for internal glob dirname Date: Tue, 21 Nov 2017 11:55:24 -0200 Message-Id: <1511272530-10936-3-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1511272530-10936-1-git-send-email-adhemerval.zanella@linaro.org> References: <1511272530-10936-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 | 270 ++++++++++++++++++++++++----------------------------------- 2 files changed, 112 insertions(+), 160 deletions(-) -- 2.7.4 diff --git a/posix/glob.c b/posix/glob.c index cb39779..7a89d2f 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"); @@ -652,10 +661,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) { @@ -664,10 +670,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') @@ -686,53 +689,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; @@ -741,23 +717,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; @@ -767,8 +743,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) { @@ -790,7 +766,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; } @@ -824,32 +801,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); - - 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; } - *((char *) mempcpy (mempcpy (dirname, p->pw_dir, home_len), - end_name, rest_len)) = '\0'; - - dirlen = home_len + rest_len; - dirname_modified = 1; + dirlen = strlen (p->pw_dir); + dirname_modified = true; } else { @@ -890,37 +848,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 @@ -933,15 +886,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)) @@ -955,7 +908,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); @@ -1002,8 +955,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; } } @@ -1025,8 +977,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, @@ -1041,8 +992,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; @@ -1068,7 +1018,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. */ @@ -1085,12 +1035,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 @@ -1108,14 +1058,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; } } } @@ -1134,8 +1083,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; @@ -1151,10 +1099,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 Tue Nov 21 13:55:25 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 119353 Delivered-To: patch@linaro.org Received: by 10.80.225.132 with SMTP id k4csp5124340edl; Tue, 21 Nov 2017 05:56:03 -0800 (PST) X-Google-Smtp-Source: AGs4zMYyUjssAgsnUFTqSX7Td8290CeTvPLh9YeMHvgNce+XaHCFdMAsd0wGjdsSL1BqGfQiObgm X-Received: by 10.98.75.77 with SMTP id y74mr15324208pfa.78.1511272563414; Tue, 21 Nov 2017 05:56:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511272563; cv=none; d=google.com; s=arc-20160816; b=gUiXRxv0ZrzEgtLrwSja6RYQ39JbJnVf3rGpTypG4vih7LL6M952BhQn+VcWZDMdAb Y39rkGIxzVZGSFpkmW/PLz6Viay26Yiqe15lItHNf64029yZUAR4CJVeq+3+WMpCQFHb kSAP4Hzs2h2VBMTm1WGFuEXE8Mocjl291jbmf50tiEvrmazYPHaVPswRESeRNlvM4TiC RGFTwkq7wT+4d2AaNASEGUNOxcG7WLag8LFXUjMSy/hd3XWdL/ZKerDzjdhn/NUqzeQK TBO2evNQJfEe3jOEeTnm0IAx2usT6EMjxvgDfC2QdK8mewdMCuuze/2tP0WltRLDEe+y p5iA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=PbDK1ZdOvAaq7/7jMNxStveY9YzGesPDcIH0wa5euRg=; b=gZPgH7VoqHx6CEwKAZCyGQQrzSpLCeADFsljMxhzAP7oFZwJ2e7mrm7nSWK736GF3q iFhEaW063rBccedzDGd/KBcoKk8A5TR6VQgYMLYUqm3ZAeSJzeCCytnObONOa07ZF5Bp lksJ9pvvHpJzpaGzbz1vJUcwrCRhSCi7l+Psl1fDcT41n0/5iQesC7BYwM0Y6acOMrsR sEpW919cHU767Kg94WkD1vwdSk7T92RTnIKgt+QpkyIva/8pkZvNCLw2bVjhZTP2qhgO 7YkkayNMKW5k10yt5zpxm1cALvap1s2u0WDujwq5HdZYnkdApXzGbzb7UXm3aIJ2IkCz K7xg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=Az8ql6w0; spf=pass (google.com: domain of libc-alpha-return-87357-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87357-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id 76si5418689pfy.58.2017.11.21.05.56.03 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Nov 2017 05:56:03 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-87357-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=Az8ql6w0; spf=pass (google.com: domain of libc-alpha-return-87357-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87357-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=TjYLq1I3MHqpvvY3/nJOjeXcNMgen1x MSLoHjkLND4u8tvO20iKfNMhMY4uPN1luQCmKugzexg4SOrWQ0wOYfjLzFG5efvg hkcEA3PT8/7BHdFxxp8yGOOPIW8+EaaamRAeGXOoHvaDoWJDrBpB6UEA/TY6M618 cUqtUOrGXAS0= 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=YtzJei3/pAZD9a/pXSqepQKBSwA=; b=Az8ql 6w0iWjZemH8wik8/82wiMvywBgAW/IGoogxUUn6Ga5wPLMDo7noxFIHhO6YvET7m p+raYsFAZ94hBRY6ktrMjvO6Sgpa914+oO56TVAdbxinXHS/QHMoET6FEZ9VN6Dr Uv5/s7aOPnAsNkn2LhS77fdk50V3Ef6jNpY7LY= Received: (qmail 44146 invoked by alias); 21 Nov 2017 13:55:46 -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 44069 invoked by uid 89); 21 Nov 2017 13:55:45 -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, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=brace X-HELO: mail-qk0-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=PbDK1ZdOvAaq7/7jMNxStveY9YzGesPDcIH0wa5euRg=; b=IvZkFAuSxi04ZQuY4SEPM+ywf4UJGzvIIfzVql2je4wHujhP2pgngfm6AgXqa2NrBZ fLHJTQtdbQZYdxbLyWTzzoN555/LR6CQQkphRpsv4HTvH7UF5KWCyOGk5GdnlPYuJIUW crt2SpdJBRY8jIBXl4xiWT7esNLAMvH9UTMtkWkcVC4tM5RWkeBdPLyhSDc4qJcFiuY4 0L2AFh4na/uUdMbfXDRk9evAOx4fj79ifHTuHeX2Rbyb8ih7nPxeGuJigJjUCfaeqOk1 6RPNy2yz5HrfNJGZ6grOdY+fAs9BSnMC7uKip5DH+SkeTB17rPAnCwhV5jI9qBdxtQUi W/bw== X-Gm-Message-State: AJaThX77zPQV+zXFUeeOaDuiEnhcLombsNVQ7qoHZGDVOyY76h9SPhUy 8bAS9pmsjd6pgpoQXTbfZ35kwPcVSZE= X-Received: by 10.55.190.135 with SMTP id o129mr347074qkf.282.1511272541885; Tue, 21 Nov 2017 05:55:41 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 3/8] posix: Remove alloca usage for GLOB_BRACE on glob Date: Tue, 21 Nov 2017 11:55:25 -0200 Message-Id: <1511272530-10936-4-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1511272530-10936-1-git-send-email-adhemerval.zanella@linaro.org> References: <1511272530-10936-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(-) -- 2.7.4 diff --git a/posix/glob.c b/posix/glob.c index 7a89d2f..7c0df0b 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 Tue Nov 21 13:55:26 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 119355 Delivered-To: patch@linaro.org Received: by 10.80.225.132 with SMTP id k4csp5124627edl; Tue, 21 Nov 2017 05:56:20 -0800 (PST) X-Google-Smtp-Source: AGs4zMaJFpvpuUdav2maey8moJhsYNoG6/Dl1IN9p7NU0BAnbMi3/rL+C1bhwJk0PhO2TJwqR6oc X-Received: by 10.98.46.7 with SMTP id u7mr15400392pfu.37.1511272580287; Tue, 21 Nov 2017 05:56:20 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511272580; cv=none; d=google.com; s=arc-20160816; b=pvYJzUsT04BhgMlSsi8gQMQYfOeXnmaKsbHRCP2f6lUGHCbGL8opR5MxlqFs2zcm6C 7tTr6Sd+Ab2WSpkfJ8RrH4/JjKYtuSqtg8Mdo8xlxkAw146WRlIx+99DVfaLjsgVV7i0 YTDw6ojcp+FZGQGPw9vN4OB/0v/tdZpwvwLVIuYgI0E5MmyRSQbw1ZnrRyptHA/mGmZF utSrP7x4JMqjs/6ApfQCEwDGIqMvKMsdWgHFpfzxfyGquxkBqo/8JbCnLzII+AOsUMpL jSRxiknoSFNv+k8IaJBOEpf1bKz92AYu8lgk6d3BC7S6EH5YezJF7dYyxVYNN+5SflHA 3NrA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=WMfViEd83XDR2t97Smk+CYiaqB4Y4RCB9oHJYK169Z4=; b=sImzD739NgKkqcdRNpHVczGpqOerbuioBiq/fulJltO9Jh9sKp16N36R1YNKXY6J7p ITelJ5QH7Lrk0EAlloyvh/rwIwbtLp0km7kic4timdSJjBs/WOaa5wuvhIk6NfDYwnoK vtnTW0ydk4C/NM33FEOPQWJ3ifw5sfXGTCUp9+DIrYBpOdOXr6RDpiIK3fD8aoWwnxHy bOZtgg0azXCbhaJzpOmOcHmtfRrky228S6l98tmzhVz1bSc3X4XEAaNoDElmJR/CCPeE GlwX50fShYtz4lSQZONXOVqzgoE89nTfZvwVyyCkXhoaBtzTbmH5sFYKE4V5r7F+7iPo Dnxg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=GdDEL+dr; spf=pass (google.com: domain of libc-alpha-return-87359-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87359-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id w5si3569018pgm.49.2017.11.21.05.56.19 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Nov 2017 05:56:20 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-87359-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=GdDEL+dr; spf=pass (google.com: domain of libc-alpha-return-87359-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87359-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=xZc3bJuX10ZkVhkCl+kmPgvpZSTLsVS 1oKedFlSIdqcV56PokdZkybTNdswZQsHmsVHIYFQGMezR3W1Icj+UjA5zrWFQn8G K9Olb4lDNOMLWh8BKmUvionAso5dHDwBo8SFQQIRi2CU3viW+XDo36X+fUL5ya4H r17Qq9cGDE/Q= 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=+VhPVqiV9nl6LCVzVp2ydAhtEX4=; b=GdDEL +drTb/h2hTkqK7c4Vc0lw+WKr5MaFbEwQtNcHpay6wlEChKphHwnT4RiMn9tSB8z zMOnM2lfp/9ICCE+S9EASsl1crm2hqVXvFDbJD3HvXySswuLu7udo0wniZB1WUUn waiD+6jJBxuJ1BCVXZL0eNJMB4B4pjPMtJAKbg= Received: (qmail 44369 invoked by alias); 21 Nov 2017 13:55:47 -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 44217 invoked by uid 89); 21 Nov 2017 13:55:46 -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, KB_WAM_FROM_NAME_SINGLEWORD, 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=WMfViEd83XDR2t97Smk+CYiaqB4Y4RCB9oHJYK169Z4=; b=JN1Q5PYtp08dJSIKIBVh3Gy3gPcAqEsrH0gSZ+zFhxPtgkwUaN82T74pJPBR0zCj7B VyHrPRo1gz5X3Sb0KLMz8fcouI29rQ/3iYZQ0pzaOTo+/MbGOlK+GM04MdRJTVElFEOJ e5ub9Z04ckVMbPjNCoyFxfKklfK/ZUBSjatIMG1u8Bu3TM0ravMI98PLGR3zGvUDSj06 hcanLZBW6ptVpddWqs/OOI8iXNysxamGtKoAHUzE0uKMiUIhv+/hR7qxGfw79HfpQPe3 VBhQEYgiWzISnR8IthOCApzj/L1R32Mv1kHgckyxdg009oJ2ubmHS7Nzi+Hpt5o1lMNY KRig== X-Gm-Message-State: AJaThX5SU1tS8DQsH8+SqlRwjwH2KT86CMlAaB/GVjG2zUYAFWkA8nYa GSxfnHZ4lx1U663COJLrXRa7DLTko7g= X-Received: by 10.55.215.221 with SMTP id t90mr5865535qkt.226.1511272543253; Tue, 21 Nov 2017 05:55:43 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 4/8] posix: Remove alloca usage on glob dirname Date: Tue, 21 Nov 2017 11:55:26 -0200 Message-Id: <1511272530-10936-5-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1511272530-10936-1-git-send-email-adhemerval.zanella@linaro.org> References: <1511272530-10936-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(-) -- 2.7.4 diff --git a/posix/glob.c b/posix/glob.c index 7c0df0b..c83954d 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -1197,7 +1197,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]; @@ -1229,32 +1228,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 Tue Nov 21 13:55:27 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 119357 Delivered-To: patch@linaro.org Received: by 10.80.225.132 with SMTP id k4csp5124980edl; Tue, 21 Nov 2017 05:56:43 -0800 (PST) X-Google-Smtp-Source: AGs4zMbIt1EomZU/oBfakC42w/hqCIL2j1CGoj6nv4RFFvxmI9kScOAjC2r2IdlzMbTAeo08HAXV X-Received: by 10.99.6.23 with SMTP id 23mr16953657pgg.276.1511272603391; Tue, 21 Nov 2017 05:56:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511272603; cv=none; d=google.com; s=arc-20160816; b=xwqYtbILMZIYUSOsNaQqMyUolLgEHBugbN6BK6+wd0wnX0tlsD7lLDDcvgrOmCVTv1 TArTyGheyhs2WWQ34GmX7zICYJgquzKMAkxKO9juTR2IwnFZL7EJ3PFwPsd0Buv+fc3y uhULHVZ/QaTX8ZVTWY/M3P/CGusxI1fjSob29zqO5weE5n6EODpcWTp6TK0i2HWTvJUJ bs3Hav7Vhni+eW4M1J5wviLMzl6Lq43TT7DcvZdKfQWqVg0M7Coho9RxmPU9WZ1Fl7JH ex4my3i4lNBdGj37lGlV2Oya3+wzCOYxkikbnFqBf1iNAkx4xx0lrMfpSS9wtfU69X33 GRVw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=PZcLXXrn4ygnX8WblCf8ReQzmBgLF67j/Z7UtyUJsmA=; b=D2psq/pYYfUeX4u3cAB23HHL0lVtPBeO+tm60PUaFMp/i180zUw86LvimsCN4jgqPq I/v7ThFFXtcetJXXO4UnuAAhbdmtGjj10tV6mFSr6cuHrs1B5klmwTNEQt5HRF6XgBt9 s4l5CFJoDwhUmfGccSQyIaofPUMo7eWIMIqUEfJiUQb9Zslue5PvUzhvlZLfrvuopO5A 0RumjKnkqayPldlwG7eP225BxsS+0fg0u0+nGvcK3ePedFT/WAacwKT607z5+RNPlD/G MFgSbjajcrZkJJQRbO3OAfuDdy+1NKrtVARqVPUcYe9+INu341ZNEq5+rnMy5Gs5/W2/ fNpg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=Bf+TP3a4; spf=pass (google.com: domain of libc-alpha-return-87361-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87361-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id l7si10972355pgn.364.2017.11.21.05.56.43 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Nov 2017 05:56:43 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-87361-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=Bf+TP3a4; spf=pass (google.com: domain of libc-alpha-return-87361-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87361-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=NNcef30mncSwXFQdQklzLuXFkmO3Ngs t6lJu9Fub6+Fa30MAwbVkIk8bCR11lVxCD56tzX3RCEZcYcOmodMHLcM16kEp9dK j2XgJnqcn955osETxZ1padnq5pxgbS9eQtY8bjVF+JJ3AaGOi039JpzB1yX5GD8S cp0Ia78iswuY= 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=O4MvwUh7rr7554we8oQBmWCpp4w=; b=Bf+TP 3a42H5NIXVqWrBEKDWV6o2utV6eMB5rXMn9UBdL7W5wthG81TfXdjMJW0/OMmKOv a7gyLL6mzYAaSJfvKuww+Gjraeamp4eGZS4wOdmzj7Sxp5Un4p3DvvmeycBzTs1j l2+zkfkyYCN8476u4UlCxwmDhlRk0ExBUjRaf8= Received: (qmail 44647 invoked by alias); 21 Nov 2017 13:55:48 -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 44595 invoked by uid 89); 21 Nov 2017 13:55:48 -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, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=135459 X-HELO: mail-qk0-f174.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=PZcLXXrn4ygnX8WblCf8ReQzmBgLF67j/Z7UtyUJsmA=; b=Y1/SlEPyt5r2ORjovvzRP1/ZAp6brKHMS6qZpd45WzuoSlfy6vF9sr0QIbrzEskQMn 3Fumzar/hHKkyyTM9mbFL6CO8/LQijWjbIVdI2WORL2uaUyriJxTTFGU9QbQ6jlgddYw zBNhoFLnv26aGXjsuWJnLadvPuK3M/7fwdtAmCuZ/CYfEcM10IM1WADR7lTVVkU9xI2/ yfgg1kXGPDDbcUTQfuiHKSPFJ94VpWd7XEGZxlImLS6I0O6q7Hmmtj5dC5LP0mZBm0KJ /OHlFlTpqLPd6nrCksdCy1ymCn7M5GttsqxZ0bdTGkOrcJdMEVPVVA5NU5iV4LJgJ2iN w/qA== X-Gm-Message-State: AJaThX5IMs04XV4BH1CL99VJNypU7Wt5AeeGzC57iuWpaBPqabTcJiNb 8LykRYKaJjfM9ywzwU6H5n+FwzOQA1Q= X-Received: by 10.55.141.68 with SMTP id p65mr1627034qkd.326.1511272544655; Tue, 21 Nov 2017 05:55:44 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 5/8] posix: Use dynarray for globname in glob Date: Tue, 21 Nov 2017 11:55:27 -0200 Message-Id: <1511272530-10936-6-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1511272530-10936-1-git-send-email-adhemerval.zanella@linaro.org> References: <1511272530-10936-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(-) -- 2.7.4 diff --git a/posix/glob.c b/posix/glob.c index c83954d..59baf62 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -1188,6 +1188,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. @@ -1198,25 +1213,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))) @@ -1293,34 +1296,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++; } } } @@ -1330,10 +1309,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; @@ -1354,59 +1336,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 Tue Nov 21 13:55:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 119358 Delivered-To: patch@linaro.org Received: by 10.80.225.132 with SMTP id k4csp5125146edl; Tue, 21 Nov 2017 05:56:54 -0800 (PST) X-Google-Smtp-Source: AGs4zMaIoChcFE+00fhv/PXDrXffxI2/lhzevjniFt3M4AURd0lQl69hhgLd3JuZVFBSk8XKkFEk X-Received: by 10.99.112.69 with SMTP id a5mr17070349pgn.179.1511272614588; Tue, 21 Nov 2017 05:56:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511272614; cv=none; d=google.com; s=arc-20160816; b=DNonRQDBrYRvWI4A+uK80X8AlcBIJOM/ftEauAV22+dhizTrtu0aiNEdgjrMR21h1R s6UXOoh9DRA8dqNk3hE8on6ERu5yA9hvSq0v7W8jmdmUTzV0q6CDxXEUsUKKfeBwKrrG SHZh6YrDA80IVbqprEsdADNZ63gP5u5WLmb6us7QIPa2qceHkxH+GgLhidb1tYHWI3kb tIfJ+PmabvejVepjcj/xXRTphSCJwQnLltZaADG/3ZuGM9vv1s0FL9QUpGPVkEWDcAlI c+4XeeSVPC8qjt6IiXGqDxXWePxxtiDlJKHvor2NGCFI8SZYlrEgrJCQ/A3oQpPo5hY+ 5KjA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=BxkRTBC9ywApgvrUMQ/OY1Tj0z9ioEHiT85vRvy/MUw=; b=m2lo/CF1/Apk44U0sEbANSSwqYTi+wIgB6Y1uywq7bP2G9i1XLNw6WNCoMd44sfhGW ja03j4orwWyT1CeV5ULaCqurziLVzmudIc9FM2k5+fBnTc+b1ndPUHUS+Go/9s6WG7jE 2Sz7nnu6A260MeO3q+WJJ5iAqr5dw6cdAokUFS5bfRjDzL5MxYaxW2dHqT0hhb7a11Zt +35nFMsjC03Ok5QvERi9zQtwolorXSGKJCepgtTgwt5+yLWvhSMCMxi1ux5V2C58WqyK nzVFnLhwPH0jFwTDGOLuWhTmY0UQh8TXuA/Dcy7oAajtbQD7Pbbo5TrN9OaA19ZsEwFH tm+A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=UTxHS8l1; spf=pass (google.com: domain of libc-alpha-return-87362-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87362-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id s14si11004430pgr.330.2017.11.21.05.56.54 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Nov 2017 05:56:54 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-87362-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=UTxHS8l1; spf=pass (google.com: domain of libc-alpha-return-87362-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87362-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=jCDyL5nzptDcaL//snXh3rj1p16GwPn T4R4DK/dcwoaiuWzp4EYkjujHbUVaxhPDPxuH86sKaVaMEO6DG1PoxqxTeupi31i eUlULKR3liqWlutajUlxayviwIFx0IsHRYa3I/+J6ETPGnYiSshZBijLo60tVZdf nojUa6U/7ICA= 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=UDFwuhV5JdstxmHXoL4YNHNAexA=; b=UTxHS 8l1fPy+3RVxueaUmIVeSxeAJlpx0PTRV4AaH6iqVnpOlB+9b3fK14xdpIOPTFR66 ibCMHZh/MWdDYAsHpP2GCF2Uuk21nc9GMr0azD+UeavAbVPTRqu5nUi4ytb/jzrg 3dVke+Wpsl+prId8CrwJ0aHPhbvhKY4vUGnJFg= Received: (qmail 44841 invoked by alias); 21 Nov 2017 13:55:50 -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 44816 invoked by uid 89); 21 Nov 2017 13:55:49 -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, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy= 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=BxkRTBC9ywApgvrUMQ/OY1Tj0z9ioEHiT85vRvy/MUw=; b=VABnFeX45pHZTYUUYM5bpJAVF9KoWXTGkiMd+gSH6x/xSL7W0JHRErwGQZ1jBx8xn9 SPq3fY3vc6TGyYitLGpM19rzvhYVcU26/nnJec1IHMNgueJx+TSW8jX2hsJPxzvKhsOY F71ixdbYA/s04AbgqJtgpxka7uf4EiTxx0NRXtT8NokdVWCI+2vPkeP0AJB1cLWM6Xes lmDvWTN4XTUO9jUAcUrM6kyrWDSn0RE5HQmWFsHd3MQsjRb8VTSMMDKtoxzLpBdjZvoI fRLrHb5x/yoVXpSNYHAxiTOhKoZSEgI749e8din/nJvq6C25r3iqXun4hYGK1XNrqVX2 6jWg== X-Gm-Message-State: AJaThX7EkjLKEVHk/gaAtXjeUTrx0CH0kU/RMQa0gUrT7wljD7rYCpa/ 2fGPaT3bqCvgGMuIfytnlSHhnSbCVuM= X-Received: by 10.200.55.53 with SMTP id o50mr26750177qtb.68.1511272545951; Tue, 21 Nov 2017 05:55:45 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 6/8] posix: Remove alloca usage on glob user_name Date: Tue, 21 Nov 2017 11:55:28 -0200 Message-Id: <1511272530-10936-7-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1511272530-10936-1-git-send-email-adhemerval.zanella@linaro.org> References: <1511272530-10936-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(-) -- 2.7.4 diff --git a/posix/glob.c b/posix/glob.c index 59baf62..aefdb28 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); @@ -712,11 +689,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)) { @@ -730,27 +706,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 == '\\') @@ -761,20 +729,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. */ @@ -786,7 +755,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) { @@ -797,11 +766,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) @@ -1024,9 +992,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 Tue Nov 21 13:55:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 119359 Delivered-To: patch@linaro.org Received: by 10.80.225.132 with SMTP id k4csp5125306edl; Tue, 21 Nov 2017 05:57:03 -0800 (PST) X-Google-Smtp-Source: AGs4zMYh6CGZyEW/g96/ftVlZN20Q8L+zwmoCmDK+ygtLWSsaLVAC1nV9PsdYiYut9Z22AeDmNsA X-Received: by 10.84.240.72 with SMTP id h8mr6727247plt.327.1511272623706; Tue, 21 Nov 2017 05:57:03 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511272623; cv=none; d=google.com; s=arc-20160816; b=cd8NmJSZ1J61aAoWwyvv7skwEqlbGe1hmTyPyrId+G+TfwP3m3CdarmVU3I1cExYur jB7KbdvFm7VFrM0dfYDD+CdhZRdAeIDSMgGnpB+plXLq/Ts0EWGIkFdnE5BPKo1um4R/ FTWonbOOwhhzi3sfxJL9ensPfg7+Lkw4Tiiw/hWHfViVODv2uOyK2PzQmJ/3BGNXQSYE VOcxLRmXAxIzwuiOTtRdqJnVBLvxAsm2XPjLXE22+jMyC5BAEqp2kEpXsrJZ4xB0Q456 hgIj36SEnoSAS7d8zJrFj7o+ALT7CLM5/uMZhXaZAm4MZ7WYLzyO2ntD2XmTq/2L718N LEKA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=RuvzQikIghan8u4dt7nEw5V9TNVl4vzshHc7seNtJKQ=; b=qs+ln37SFFV17GLF9yvWf06E3PMwzSEzEwt7vQ8wngylKjx/Qfbq7FUZp3XbXKLekw 8qHPLhTdYe/cYFzIfvd24Ae+VBz6vBccRxpuGVaM7MnCaTFOWdh65k8Vw0/ONK7hDJcs 4eSmEB6FTGISjtFbEJhW4UjT41Nc8HS4ziWW61EgNTi/2N8KmV0QbgStqcvgXPk1ZX4U +YSyzPsMHFM4kcZCCVgYuurzRJunyNztZl1bPp1xbgp0RoyNxApw/nzNhskEglzx503G /Nmwu025bJ/YJ3BAeLMsjGWiFhZeasM/h9SZAeBvV4HmSHcUoHrGhg03i77F6X7IRTnk hpCg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=VpmacF5+; spf=pass (google.com: domain of libc-alpha-return-87363-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87363-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id c11si10612629pll.792.2017.11.21.05.57.03 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Nov 2017 05:57:03 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-87363-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=VpmacF5+; spf=pass (google.com: domain of libc-alpha-return-87363-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87363-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=dGZV5O6bUxVqq4U3cm+4hAfzt9cbIjI 8sjUUroUCiHbB8CZupkh4RlvnPbMZyzTsdvnNbuBrE55V5RZjgNyEakh3t4Ur2ha PsFHSswRJLHUklwxZw56d5MuvdD9uNSPZYvsQrwRqVSylteK7KMxDjLTBSaS6Kz1 KKRV/3r4cJSs= 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=sCozfV+vSGjPzWX/qz2HhtqW5c4=; b=Vpmac F5+hnsvh0Cpi7ei8jchBRNRBAqQ0XPpJ+sSdVbVn7GqDuYusiyU0VH1VZ6u3WCya zKkU2GZcaiK9jQgfQvevyjDGuCpRQy+sPvaeaVXVc4G2ItlQgixxifnhX7ro/ktr tFi7J3NcI7VawMPBOAiAC6slSXqTjn5LmOWoEo= Received: (qmail 45027 invoked by alias); 21 Nov 2017 13:55:51 -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 45002 invoked by uid 89); 21 Nov 2017 13:55:50 -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, KB_WAM_FROM_NAME_SINGLEWORD, 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=RuvzQikIghan8u4dt7nEw5V9TNVl4vzshHc7seNtJKQ=; b=DjHsiOCXjTE8J++BGt3T9dF6z9bMeHrIxLUQAR59HM2Y3/zV4xMp5k82luMhFH2UA4 ja3096LjZ5KhJWAKeiwCfoEJNH9BIUc61PA2iTUcAaI/ZkY1fkWpKkaZGkgNPt/6lzUf RlvW2mmjpNORa95qWR8aS0wC44g6GJArCZ7fBf1Zu+MmMm/fVjjE+PmVOI8rfih3Friw MKB/s0ptLSjYNmlm2amUbtXPsJ2fX3Da/yoeRC0EDql35qNARYwNH8P5CSUA1R6mOSo/ g6JSng9/pQrgJM2SixCb+UhMlK6/0qBSDH4CIIip/0ypY8YZaLk/rx4aE18ytr6H2+d3 pKkA== X-Gm-Message-State: AJaThX4aviUzC3vq3oCnPGYbIVAub5cwTJO6O/dS2do7vVvnyDQLA0yH L+OYk6p+IppoNxZmGkPs6wiDbeVKPFM= X-Received: by 10.200.40.157 with SMTP id i29mr26896380qti.86.1511272547269; Tue, 21 Nov 2017 05:55:47 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 7/8] posix: Use char_array for home_dir in glob Date: Tue, 21 Nov 2017 11:55:29 -0200 Message-Id: <1511272530-10936-8-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1511272530-10936-1-git-send-email-adhemerval.zanella@linaro.org> References: <1511272530-10936-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(-) -- 2.7.4 diff --git a/posix/glob.c b/posix/glob.c index aefdb28..71807d6 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; @@ -645,44 +655,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 Tue Nov 21 13:55:30 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 119360 Delivered-To: patch@linaro.org Received: by 10.80.225.132 with SMTP id k4csp5125486edl; Tue, 21 Nov 2017 05:57:14 -0800 (PST) X-Google-Smtp-Source: AGs4zMaLNalF/wS5lidt+q6SjtUw19C3YLXs6nxI4RsqWAxsy5pbBVDTKnsqEaCLLPqtn5gmf3s2 X-Received: by 10.159.207.149 with SMTP id z21mr18189062plo.164.1511272634636; Tue, 21 Nov 2017 05:57:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1511272634; cv=none; d=google.com; s=arc-20160816; b=0zRlWLCC5GGXyMDCelAg7+qpSvdUGWGAWDietfoCoaxQ9W1KmRUhEkQFyQK2Cht1SO SwfN5prlwQ/u/hViKr3XzZi/lTIqn0BDc+x5B3ir3wU1Hdc2FVq5S0Q0Wh5bWC39m/Dh 3uT3gdCtTxDV0ukf18kp54Pceo4Y/XHirx+f5VihROx7Mc+MBydg1xXlARlxZGuLCsgU TQv8NXmT4cVR3mSPyQW+72Tmx7Dyfdoh1mkQEI+icjYbc9qcB6T8fLorXsNaenSqg5OP 5Bq7rhfUWmGeVRvEWjjIdu1i5fX5wGxNVMLaKIMbGrOLFUDneHrj1Cm2/Fax6QUDxh35 lC6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:to:from:delivered-to :sender:list-help:list-post:list-archive:list-subscribe :list-unsubscribe:list-id:precedence:mailing-list:dkim-signature :domainkey-signature:arc-authentication-results; bh=mqznf0jFwl3abYRv57lLdH9MckAo8tbCE27iiDmt/Ck=; b=hYv6uvUAkz0uNn60GYJQTq9gnvX2Hfz2Ff+HK7O1B1oPcohE2M6Wp/Y3VUNkqCZkf2 mh1pDRhxeaIGJRpEOJWH4uLmZHVLNRYXSkuNLUOXHDfFaVmbZGaI7InZu5NXxETbYt0Q SSt1VB/fd0YPIUf5sfQ1PZnte02AM8peoIV2JVgxt8WRU+x8LzUv/cihoNYxtEfvKY7H m/z+JxyWa/AGYj13FC++fWvm/42EYTC3XQPC1iQKBhB3eqlVQbZQdnYcgeg1jveMmxaO BK7KdirWGXVbfsegT6Ni+gfrgkJ4LcN1TYGvK7L6SgdcBxa5IHGPPWecH3DVWb9WoCuc xabQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=JXeh0S6Z; spf=pass (google.com: domain of libc-alpha-return-87364-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87364-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id w9si9769411plp.333.2017.11.21.05.57.14 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 21 Nov 2017 05:57:14 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-87364-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=JXeh0S6Z; spf=pass (google.com: domain of libc-alpha-return-87364-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-87364-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:in-reply-to :references; q=dns; s=default; b=u0j9H2owVKdxC5wAfFA80pdW27FiwqC T7hUZmC2HagZepzceU7Yontd6A1x+TlAM2MGQuTxEAc02DrizNG90Bk0aMVhvs7U OS7784QpgZKErxGilj06MiwHz7M77hCt0RM9c28KTCuaQjOcjtUw26e0GIY7/tMl MIq3XYct5GzU= 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=fo1uPMAudU5cvguA1TYCkr9zpwc=; b=JXeh0 S6ZFlkaZHCbTJ6foLq95M69cI1nbz9UCt9lBYVjaxg2JpRIvVk1eqTvNr9OCfkIL kbDr5LOMQu4v211zmGPcQ5F6z9DUNaewwiI3jbk+SJxWUpoGiSii2W6jDbmeppGQ WMFKz4+YSarKb+jdJ/rOvPZOIuhsW6+EcYxnd4= Received: (qmail 45183 invoked by alias); 21 Nov 2017 13:55: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 45162 invoked by uid 89); 21 Nov 2017 13:55: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, KB_WAM_FROM_NAME_SINGLEWORD, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=1706, fname 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=mqznf0jFwl3abYRv57lLdH9MckAo8tbCE27iiDmt/Ck=; b=F/AkhYM95arz1EvCSEPapWGJp/ZT/1RsFzBwxD2jnwDySlJT2tBsqjOTOBryDSEcoz 6riPZG7fWr6R/eWmrdHa2PSbL8AVsi67P510h8mt6mdb/vLNt4LCSHagSQ2/Cm7OD986 AcPcNQjiEtj5U871YDJI9op3IDG9fWEAclKxnQTIPd/MTwmT2yA+ojcAoSfbo9LUUwxR Yc42DkEvfsvf1C9pecisH4oFS2i2xenqwKnIU9uNVfMj0GF39OuBcyiUwnBgABUNVjBT FCR/ehk9m+L6t7j/GXST4mG0Xdw32wljKCflevgYQtaSxg/XC1QXB76ej+5g3L3Zys59 htKg== X-Gm-Message-State: AJaThX4exWsOVpktjt2Pn1zyRAOUDyaHgFHcMIIjEwia8BzOf1NFAsqn a7SVPDiGnv75V1o98Uq7bjlvDlsfwKk= X-Received: by 10.55.58.14 with SMTP id h14mr24670842qka.132.1511272548598; Tue, 21 Nov 2017 05:55:48 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH 8/8] posix: Remove all alloca usage in glob Date: Tue, 21 Nov 2017 11:55:30 -0200 Message-Id: <1511272530-10936-9-git-send-email-adhemerval.zanella@linaro.org> In-Reply-To: <1511272530-10936-1-git-send-email-adhemerval.zanella@linaro.org> References: <1511272530-10936-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(-) -- 2.7.4 diff --git a/posix/glob.c b/posix/glob.c index 71807d6..4d40c4c 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; @@ -920,7 +911,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; @@ -1025,7 +1016,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 @@ -1190,7 +1181,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;