From patchwork Mon Jan 4 20:25:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 41635 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6AE803858018; Mon, 4 Jan 2021 20:25:37 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 6AE803858018 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1609791937; bh=3H+RWXDKZAM2PpS/flEwWQuynf/UrJKZsy9zqIGb/ik=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=kpaaj1UOChkq2ghvRIA6aAv3pg5Y1mO5Nb5gRl9YIznxHOIIWuUefMNjcbZozFyfO oePEDTCO7sN6S09uqwVaewizHjRYPPOXptJjIFzNJfJKKWu0R8TvjHr3tCmXxx9gJA dEbUpsvyELbQV4WcFzt6H6bnoJ7rH/teRNkQvUNQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-qt1-x82f.google.com (mail-qt1-x82f.google.com [IPv6:2607:f8b0:4864:20::82f]) by sourceware.org (Postfix) with ESMTPS id 6EBE63858018 for ; Mon, 4 Jan 2021 20:25:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 6EBE63858018 Received: by mail-qt1-x82f.google.com with SMTP id j26so19387037qtq.8 for ; Mon, 04 Jan 2021 12:25:34 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=3H+RWXDKZAM2PpS/flEwWQuynf/UrJKZsy9zqIGb/ik=; b=Mru0V/KsRTd1OfKcrfvg7QBjLZ6jqXjHWtYfYYUNTPTH+SDravYn/U/WkrHrvPYfTA YId/cFXiOKop30Lj9XLAVK+ePbgIQblMhofSB4cL2OC5NG7L+xBBWk+a95NDSoKXBJmT TYhVLTwie6sVNvq18KQO4iCWLu3usnsRaFC+t0UTaDbHiEhKGQbQBtjyvh64zzQUU5c8 43zQ6ILSTwE9RSd95qXSUhA71GniebGFhlT8z90aY5L0PnTUB2IFhEUKYw4lzt341YHi KB8yr6VRcMV0VGFkmFdODhuLCODDdpgndURZQGfJhUp7BXZNMKcD66N+eFL+FLbzOftg 8mZA== X-Gm-Message-State: AOAM530b+9YbSAmNM29/EoZ2jIanhK0DTQB3hUSYlF/L/DKVhMnZm8oE gF6uxPYc7yKtFt3i8GVuiKoaUPBuph4BKA== X-Google-Smtp-Source: ABdhPJxj/BZdyHHqGkNyUIGVs6j2rVfngvRydE2BElc8UQ9hU7lt3KKkVoLmugRUKYRadYbFQmiS/Q== X-Received: by 2002:ac8:6f07:: with SMTP id g7mr73365981qtv.308.1609791933655; Mon, 04 Jan 2021 12:25:33 -0800 (PST) Received: from localhost.localdomain ([177.194.48.209]) by smtp.googlemail.com with ESMTPSA id b4sm36292928qtb.33.2021.01.04.12.25.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Jan 2021 12:25:33 -0800 (PST) To: libc-alpha@sourceware.org, Paul Eggert Subject: [PATCH 1/2] posix: User scratch_buffer on fnmatch Date: Mon, 4 Jan 2021 17:25:27 -0300 Message-Id: <20210104202528.1228255-1-adhemerval.zanella@linaro.org> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-Spam-Status: No, score=-13.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Adhemerval Zanella via Libc-alpha From: Adhemerval Zanella Netto Reply-To: Adhemerval Zanella Cc: bug-gnulib@gnu.org Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" It removes the alloca usage on the string convertion to wide characters before calling the internal function. Checked on x86_64-linux-gnu. --- posix/fnmatch.c | 152 +++++++++++++++++------------------------------- 1 file changed, 53 insertions(+), 99 deletions(-) diff --git a/posix/fnmatch.c b/posix/fnmatch.c index 5896812c96..ac254fc9ac 100644 --- a/posix/fnmatch.c +++ b/posix/fnmatch.c @@ -75,6 +75,7 @@ extern int fnmatch (const char *pattern, const char *string, int flags); #include #include +#include #ifdef _LIBC typedef ptrdiff_t idx_t; @@ -231,119 +232,72 @@ is_char_class (const wchar_t *wcs) #include "fnmatch_loop.c" +static int +fnmatch_convert_to_wide (const char *str, struct scratch_buffer *buf, + size_t *n) +{ + mbstate_t ps; + memset (&ps, '\0', sizeof (ps)); + + size_t nw = buf->length / sizeof (wchar_t); + *n = strnlen (str, nw - 1); + if (__glibc_likely (*n < nw)) + { + const char *p = str; + *n = mbsrtowcs (buf->data, &p, *n + 1, &ps); + if (__glibc_unlikely (*n == (size_t) -1)) + /* Something wrong. + XXX Do we have to set 'errno' to something which mbsrtows hasn't + already done? */ + return -1; + if (p == NULL) + return 0; + memset (&ps, '\0', sizeof (ps)); + } + + *n = mbsrtowcs (NULL, &str, 0, &ps); + if (__glibc_unlikely (*n == (size_t) -1)) + return -1; + if (!scratch_buffer_set_array_size (buf, *n + 1, sizeof (wchar_t))) + { + __set_errno (ENOMEM); + return -2; + } + assert (mbsinit (&ps)); + mbsrtowcs (buf->data, &str, *n + 1, &ps); + return 0; +} int fnmatch (const char *pattern, const char *string, int flags) { if (__glibc_unlikely (MB_CUR_MAX != 1)) { - mbstate_t ps; size_t n; - const char *p; - wchar_t *wpattern_malloc = NULL; - wchar_t *wpattern; - wchar_t *wstring_malloc = NULL; - wchar_t *wstring; - size_t alloca_used = 0; + struct scratch_buffer wpattern; + scratch_buffer_init (&wpattern); + struct scratch_buffer wstring; + scratch_buffer_init (&wstring); + int r; /* Convert the strings into wide characters. */ - memset (&ps, '\0', sizeof (ps)); - p = pattern; - n = strnlen (pattern, 1024); - if (__glibc_likely (n < 1024)) - { - wpattern = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t), - alloca_used); - n = mbsrtowcs (wpattern, &p, n + 1, &ps); - if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong. - XXX Do we have to set 'errno' to something which mbsrtows hasn't - already done? */ - return -1; - if (p) - { - memset (&ps, '\0', sizeof (ps)); - goto prepare_wpattern; - } - } - else - { - prepare_wpattern: - n = mbsrtowcs (NULL, &pattern, 0, &ps); - if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong. - XXX Do we have to set 'errno' to something which mbsrtows hasn't - already done? */ - return -1; - if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) - { - __set_errno (ENOMEM); - return -2; - } - wpattern_malloc = wpattern - = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t)); - assert (mbsinit (&ps)); - if (wpattern == NULL) - return -2; - (void) mbsrtowcs (wpattern, &pattern, n + 1, &ps); - } - - assert (mbsinit (&ps)); - n = strnlen (string, 1024); - p = string; - if (__glibc_likely (n < 1024)) - { - wstring = (wchar_t *) alloca_account ((n + 1) * sizeof (wchar_t), - alloca_used); - n = mbsrtowcs (wstring, &p, n + 1, &ps); - if (__glibc_unlikely (n == (size_t) -1)) - { - /* Something wrong. - XXX Do we have to set 'errno' to something which - mbsrtows hasn't already done? */ - free_return: - free (wpattern_malloc); - return -1; - } - if (p) - { - memset (&ps, '\0', sizeof (ps)); - goto prepare_wstring; - } - } - else + r = fnmatch_convert_to_wide (pattern, &wpattern, &n); + if (r != 0) + return r; + r = fnmatch_convert_to_wide (string, &wstring, &n); + if (r != 0) { - prepare_wstring: - n = mbsrtowcs (NULL, &string, 0, &ps); - if (__glibc_unlikely (n == (size_t) -1)) - /* Something wrong. - XXX Do we have to set 'errno' to something which mbsrtows hasn't - already done? */ - goto free_return; - if (__glibc_unlikely (n >= (size_t) -1 / sizeof (wchar_t))) - { - free (wpattern_malloc); - __set_errno (ENOMEM); - return -2; - } - - wstring_malloc = wstring - = (wchar_t *) malloc ((n + 1) * sizeof (wchar_t)); - if (wstring == NULL) - { - free (wpattern_malloc); - return -2; - } - assert (mbsinit (&ps)); - (void) mbsrtowcs (wstring, &string, n + 1, &ps); + scratch_buffer_free (&wpattern); + return n; } - int res = internal_fnwmatch (wpattern, wstring, wstring + n, + int res = internal_fnwmatch (wpattern.data, wstring.data, + (wchar_t *) wstring.data + n, flags & FNM_PERIOD, flags, NULL, - alloca_used); + false); - free (wstring_malloc); - free (wpattern_malloc); + scratch_buffer_free (&wstring); + scratch_buffer_free (&wpattern); return res; }