From patchwork Thu Oct 15 15:22:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 530758 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 753AA1402B2 for ; Fri, 16 Oct 2015 02:22:48 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b=eM4JsKE9; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:to:from:subject:message-id:date:mime-version :content-type; q=dns; s=default; b=M0pDr61dXpgNDOwbGQUlcD6vrQeTr nluhU2XDPCIMJFyj/pzCFyN5+sPLi0EtDkud33FMxN44yl+ZIwIz5ffzH3giMNco MPlMkztHKXhggja04szEqWUFJfH3Mx9tY8ONCqEoy3em4oQHrqZRBAjoZSmImTo5 oajXXVYIaOkeZI= 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:to:from:subject:message-id:date:mime-version :content-type; s=default; bh=vAbiNJBfxUsOJKQYnKKMmNGv/Ws=; b=eM4 JsKE949oHYFwe4G9GpR4Vqr/tfrTbNXAz90RxQCpwWJa+sTVDiS9AaZ3bHd/wiDl 6nnDrnjwcADtPiXhHgcr8pFgUJSRVYy620Ed0j+a4O4qRnwSwVyMNx1OcKvIhbzL x7meP0sxlJtF3h0qmnozNN82S56gkmhMnTgLzvso= Received: (qmail 127450 invoked by alias); 15 Oct 2015 15:22:40 -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 127441 invoked by uid 89); 15 Oct 2015 15:22:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, T_RP_MATCHES_RCVD, UNSUBSCRIBE_BODY autolearn=no version=3.3.2 X-HELO: mx1.redhat.com To: GNU C Library From: Florian Weimer Subject: [PATCH v2] vfprintf: Rewrite printf_positional to use struct scratch_buffer X-Enigmail-Draft-Status: N1110 Message-ID: <561FC4BC.5040304@redhat.com> Date: Thu, 15 Oct 2015 17:22:36 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 This rebase picks up the specs_malloced/args_malloced fix in commit 560b04462f899e76a0062ec89422caa6e94fd67f. Florian 2015-10-15 Florian Weimer * stdio-common/vfprintf.c (printf_positional): Rewrite to use struct scratch_buffer instead of extend_alloca. diff --git a/stdio-common/vfprintf.c b/stdio-common/vfprintf.c index 5e408d2..ae01452 100644 --- a/stdio-common/vfprintf.c +++ b/stdio-common/vfprintf.c @@ -29,6 +29,7 @@ #include <_itoa.h> #include #include +#include /* This code is shared between the standard stdio implementation found in GNU C library and the libio implementation originally found in @@ -1698,18 +1699,15 @@ printf_positional (_IO_FILE *s, const CHAR_T *format, int readonly_format, void *args_malloced = NULL; /* For positional argument handling. */ - struct printf_spec *specs; - - /* Track if we malloced the SPECS array and thus must free it. */ - bool specs_malloced = false; + struct scratch_buffer specsbuf; + scratch_buffer_init (&specsbuf); + struct printf_spec *specs = specsbuf.data; + size_t specs_limit = specsbuf.length / sizeof (specs[0]); /* Array with information about the needed arguments. This has to be dynamically extensible. */ size_t nspecs = 0; - /* A more or less arbitrary start value. */ - size_t nspecs_size = 32 * sizeof (struct printf_spec); - specs = alloca (nspecs_size); /* The number of arguments the format string requests. This will determine the size of the array needed to store the argument attributes. */ @@ -1746,42 +1744,15 @@ printf_positional (_IO_FILE *s, const CHAR_T *format, int readonly_format, for (const UCHAR_T *f = lead_str_end; *f != L_('\0'); f = specs[nspecs++].next_fmt) { - if (nspecs * sizeof (*specs) >= nspecs_size) + if (nspecs == specs_limit) { - /* Extend the array of format specifiers. */ - if (nspecs_size * 2 < nspecs_size) + if (!scratch_buffer_grow_preserve (&specsbuf)) { - __set_errno (ENOMEM); done = -1; goto all_done; } - struct printf_spec *old = specs; - if (__libc_use_alloca (2 * nspecs_size)) - specs = extend_alloca (specs, nspecs_size, 2 * nspecs_size); - else - { - nspecs_size *= 2; - specs = malloc (nspecs_size); - if (specs == NULL) - { - __set_errno (ENOMEM); - specs = old; - done = -1; - goto all_done; - } - } - - /* Copy the old array's elements to the new space. */ - memmove (specs, old, nspecs * sizeof (*specs)); - - /* If we had previously malloc'd space for SPECS, then - release it after the copy is complete. */ - if (specs_malloced) - free (old); - - /* Now set SPECS_MALLOCED if needed. */ - if (!__libc_use_alloca (nspecs_size)) - specs_malloced = true; + specs = specsbuf.data; + specs_limit = specsbuf.length / sizeof (specs[0]); } /* Parse the format specifier. */ @@ -2091,12 +2062,11 @@ printf_positional (_IO_FILE *s, const CHAR_T *format, int readonly_format, - specs[nspecs_done].end_of_fmt); } all_done: - if (__glibc_unlikely (specs_malloced)) - free (specs); if (__glibc_unlikely (args_malloced != NULL)) free (args_malloced); if (__glibc_unlikely (workstart != NULL)) free (workstart); + scratch_buffer_free (&specsbuf); return done; }