From patchwork Thu Feb 6 02:21:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Sommerseth X-Patchwork-Id: 984 Return-Path: Delivered-To: patchwork@openvpn.net Delivered-To: patchwork@openvpn.net Received: from director10.mail.ord1d.rsapps.net ([172.30.191.6]) by backend30.mail.ord1d.rsapps.net with LMTP id +Gn2M5UWPF5HPQAAIUCqbw for ; Thu, 06 Feb 2020 08:37:25 -0500 Received: from proxy8.mail.ord1d.rsapps.net ([172.30.191.6]) by director10.mail.ord1d.rsapps.net with LMTP id CMWaM5UWPF6PJgAApN4f7A ; Thu, 06 Feb 2020 08:37:25 -0500 Received: from smtp10.gate.ord1c ([172.30.191.6]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) by proxy8.mail.ord1d.rsapps.net with LMTP id eIkWM5UWPF5wYgAAGdz6CA ; Thu, 06 Feb 2020 08:37:25 -0500 X-Spam-Threshold: 95 X-Spam-Score: 0 X-Spam-Flag: NO X-Virus-Scanned: OK X-Orig-To: openvpnslackdevel@openvpn.net X-Originating-Ip: [216.105.38.7] Authentication-Results: smtp10.gate.ord1c.rsapps.net; iprev=pass policy.iprev="216.105.38.7"; spf=pass smtp.mailfrom="openvpn-devel-bounces@lists.sourceforge.net" smtp.helo="lists.sourceforge.net"; dkim=fail (signature verification failed) header.d=sourceforge.net; dkim=fail (signature verification failed) header.d=sf.net; dmarc=fail (p=none; dis=none) header.from=openvpn.net X-Suspicious-Flag: YES X-Classification-ID: cee8a394-48e5-11ea-8ce4-0026b954785f-1-1 Received: from [216.105.38.7] ([216.105.38.7:35416] helo=lists.sourceforge.net) by smtp10.gate.ord1c.rsapps.net (envelope-from ) (ecelerity 4.2.38.62370 r(:)) with ESMTPS (cipher=DHE-RSA-AES256-GCM-SHA384) id 8C/C0-11066-4961C3E5; Thu, 06 Feb 2020 08:37:25 -0500 Received: from [127.0.0.1] (helo=sfs-ml-1.v29.lw.sourceforge.com) by sfs-ml-1.v29.lw.sourceforge.com with esmtp (Exim 4.90_1) (envelope-from ) id 1izhJL-0000KA-Jj; Thu, 06 Feb 2020 13:35:15 +0000 Received: from [172.30.20.202] (helo=mx.sourceforge.net) by sfs-ml-1.v29.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.90_1) (envelope-from ) id 1izhJJ-0000Jh-NA for openvpn-devel@lists.sourceforge.net; Thu, 06 Feb 2020 13:35:13 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sourceforge.net; s=x; h=References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Sender:Reply-To:MIME-Version:Content-Type:Content-Transfer-Encoding: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help:List-Unsubscribe: List-Subscribe:List-Post:List-Owner:List-Archive; bh=aoooKw3+nAsDWu57VUaHXZeRysWPcYc8uFMCimMV28Q=; b=krzzuTItsYX6zKiRble/6OtWTi vujpEZC78fX6fh1GxUYanpN2zNjxDfhooU8t2aRijcY2XtdSJT75gePpPXYGAhreXF8arlxdFzgw0 D2peQ7w3VX4DQbNbeQCWovU8mNCDbKPEGEmAu1/SPrmkvuBsq/cz3/lj9lzvHU6u/z/k=; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=sf.net; s=x ; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To :MIME-Version:Content-Type:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=aoooKw3+nAsDWu57VUaHXZeRysWPcYc8uFMCimMV28Q=; b=IEkGr3X1JUCZl9IuArXgjB102M TsCnYTe+TUT9wKUJCYkhJcXgT7SY99XbmU7zLr/9PPSFHE72mGXLwkkHjq3l/y+hWaYbnCXvIaNUe c3tr03kSTUwsVLktZpZAVgUxn9BiwbV4tgzBODb+v2b9dFK1LytiNHp3pX+W+PTAHBT0=; Received: from mx0.basenordic.cloud ([185.212.44.139]) by sfi-mx-1.v28.lw.sourceforge.com with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92.2) id 1izhJH-001N3G-Qh for openvpn-devel@lists.sourceforge.net; Thu, 06 Feb 2020 13:35:13 +0000 Received: from localhost (unknown [IPv6:::1]) by mx0.basenordic.cloud (Postfix) with ESMTP id 29B75838A09; Thu, 6 Feb 2020 13:21:28 +0000 (UTC) Received: from mx0.basenordic.cloud ([IPv6:::1]) by localhost (winterfell.topphemmelig.net [IPv6:::1]) (amavisd-new, port 10024) with ESMTP id 6qb7kpv-3Llw; Thu, 6 Feb 2020 14:21:24 +0100 (CET) Received: from zimbra.sommerseth.email (zimbra.sommerseth.email [172.16.33.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx0.basenordic.cloud (Postfix) with ESMTPS id 8CC46837ABE; Thu, 6 Feb 2020 14:21:24 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by zimbra.sommerseth.email (Postfix) with ESMTP id 09E61401D334; Thu, 6 Feb 2020 14:21:24 +0100 (CET) Received: from zimbra.sommerseth.email ([127.0.0.1]) by localhost (zimbra.sommerseth.email [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 26rgR0TDwLZq; Thu, 6 Feb 2020 14:21:23 +0100 (CET) Received: from optimus.homebase.sommerseths.net (unknown [10.35.7.3]) by zimbra.sommerseth.email (Postfix) with ESMTPS id A3BF6401D33B; Thu, 6 Feb 2020 14:21:22 +0100 (CET) From: David Sommerseth To: openvpn-devel@lists.sourceforge.net Date: Thu, 6 Feb 2020 14:21:02 +0100 Message-Id: <20200206132103.15977-4-davids@openvpn.net> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200206132103.15977-1-davids@openvpn.net> References: <20200206132103.15977-1-davids@openvpn.net> X-Spam-Report: Spam Filtering performed by mx.sourceforge.net. See http://spamassassin.org/tag/ for more details. 0.0 URIBL_BLOCKED ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [URIs: openvpn.net] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record 0.2 HEADER_FROM_DIFFERENT_DOMAINS From and EnvelopeFrom 2nd level mail domains are different -0.0 SPF_PASS SPF: sender matches SPF record X-Headers-End: 1izhJH-001N3G-Qh Subject: [Openvpn-devel] [PATCH 3/4] Add gc_arena to struct argv to save allocations X-BeenThere: openvpn-devel@lists.sourceforge.net X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: openvpn-devel-bounces@lists.sourceforge.net X-getmail-retrieved-from-mailbox: Inbox From: Heiko Hund With the private gc_arena we do not have to allocate the strings found during parsing again, since we know the arena they are allocated in is valid as long as the argv vector is. Signed-off-by: Heiko Hund Signed-off-by: David Sommerseth Acked-By: Arne Schwabe --- src/openvpn/argv.c | 50 ++++++++++++---------------- src/openvpn/argv.h | 1 + tests/unit_tests/openvpn/test_argv.c | 23 +++++++++++++ 3 files changed, 45 insertions(+), 29 deletions(-) diff --git a/src/openvpn/argv.c b/src/openvpn/argv.c index 4f7aa4e5..7d949d24 100644 --- a/src/openvpn/argv.c +++ b/src/openvpn/argv.c @@ -47,12 +47,11 @@ argv_extend(struct argv *a, const size_t newcap) { char **newargv; size_t i; - ALLOC_ARRAY_CLEAR(newargv, char *, newcap); + ALLOC_ARRAY_CLEAR_GC(newargv, char *, newcap, &a->gc); for (i = 0; i < a->argc; ++i) { newargv[i] = a->argv[i]; } - free(a->argv); a->argv = newargv; a->capacity = newcap; } @@ -64,6 +63,7 @@ argv_init(struct argv *a) a->capacity = 0; a->argc = 0; a->argv = NULL; + a->gc = gc_new(); argv_extend(a, 8); } @@ -78,24 +78,21 @@ argv_new(void) void argv_free(struct argv *a) { - size_t i; - for (i = 0; i < a->argc; ++i) - { - free(a->argv[i]); - } - free(a->argv); + gc_free(&a->gc); } static void argv_reset(struct argv *a) { - size_t i; - for (i = 0; i < a->argc; ++i) + if (a->argc) { - free(a->argv[i]); - a->argv[i] = NULL; + size_t i; + for (i = 0; i < a->argc; ++i) + { + a->argv[i] = NULL; + } + a->argc = 0; } - a->argc = 0; } static void @@ -107,7 +104,7 @@ argv_grow(struct argv *a, const size_t add) } static void -argv_append(struct argv *a, char *str) /* str must have been malloced or be NULL */ +argv_append(struct argv *a, char *str) /* str must have been gc_malloced or be NULL */ { argv_grow(a, 1); a->argv[a->argc++] = str; @@ -127,7 +124,7 @@ argv_clone(const struct argv *a, const size_t headroom) { for (size_t i = 0; i < a->argc; ++i) { - argv_append(&r, string_alloc(a->argv[i], NULL)); + argv_append(&r, string_alloc(a->argv[i], &r.gc)); } } return r; @@ -138,7 +135,7 @@ argv_insert_head(const struct argv *a, const char *head) { struct argv r; r = argv_clone(a, 1); - r.argv[0] = string_alloc(head, NULL); + r.argv[0] = string_alloc(head, &r.gc); return r; } @@ -222,7 +219,6 @@ argv_prep_format(const char *format, const char delim, size_t *count, struct gc_ static bool argv_printf_arglist(struct argv *a, const char *format, va_list arglist) { - struct gc_arena gc = gc_new(); const char delim = 0x1D; /* ASCII Group Separator (GS) */ bool res = false; @@ -236,7 +232,7 @@ argv_printf_arglist(struct argv *a, const char *format, va_list arglist) * */ size_t argc = a->argc; - char *f = argv_prep_format(format, delim, &argc, &gc); + char *f = argv_prep_format(format, delim, &argc, &a->gc); if (f == NULL) { goto out; @@ -256,8 +252,8 @@ argv_printf_arglist(struct argv *a, const char *format, va_list arglist) * Do the actual vsnprintf() operation, which expands the format * string with the provided arguments. */ - size_t size = len + 1; - char *buf = gc_malloc(size, false, &gc); + size_t size = adjust_power_of_2(len + 1); + char *buf = gc_malloc(size, false, &a->gc); len = vsnprintf(buf, size, f, arglist); if (len < 0 || len >= size) { @@ -272,11 +268,11 @@ argv_printf_arglist(struct argv *a, const char *format, va_list arglist) while (end) { *end = '\0'; - argv_append(a, string_alloc(buf, NULL)); + argv_append(a, buf); buf = end + 1; end = strchr(buf, delim); } - argv_append(a, string_alloc(buf, NULL)); + argv_append(a, buf); if (a->argc != argc) { @@ -287,7 +283,6 @@ argv_printf_arglist(struct argv *a, const char *format, va_list arglist) res = true; out: - gc_free(&gc); return res; } @@ -321,21 +316,18 @@ argv_parse_cmd(struct argv *a, const char *s) { argv_reset(a); - struct gc_arena gc = gc_new(); char *parms[MAX_PARMS + 1] = { 0 }; - int nparms = parse_line(s, parms, MAX_PARMS, "SCRIPT-ARGV", 0, D_ARGV_PARSE_CMD, &gc); + int nparms = parse_line(s, parms, MAX_PARMS, "SCRIPT-ARGV", 0, D_ARGV_PARSE_CMD, &a->gc); if (nparms) { int i; for (i = 0; i < nparms; ++i) { - argv_append(a, string_alloc(parms[i], NULL)); + argv_append(a, parms[i]); } } else { - argv_append(a, string_alloc(s, NULL)); + argv_append(a, string_alloc(s, &a->gc)); } - - gc_free(&gc); } diff --git a/src/openvpn/argv.h b/src/openvpn/argv.h index 989cd297..943c78ef 100644 --- a/src/openvpn/argv.h +++ b/src/openvpn/argv.h @@ -33,6 +33,7 @@ #include "buffer.h" struct argv { + struct gc_arena gc; size_t capacity; size_t argc; char **argv; diff --git a/tests/unit_tests/openvpn/test_argv.c b/tests/unit_tests/openvpn/test_argv.c index fde0ba45..25e80c1c 100644 --- a/tests/unit_tests/openvpn/test_argv.c +++ b/tests/unit_tests/openvpn/test_argv.c @@ -117,6 +117,28 @@ argv_printf__empty_parameter__argc_correct(void **state) argv_free(&a); } +static void +argv_printf__long_args__data_correct(void **state) +{ + int i; + struct argv a = argv_new(); + const char *args[] = { + "good_tools_have_good_names_even_though_it_might_impair_typing", + "--long-opt=looooooooooooooooooooooooooooooooooooooooooooooooong", + "--long-cat=loooooooooooooooooooooooooooooooooooooooooooooooooooonger", + "file_with_very_descriptive_filename_that_leaves_no_questions_open.jpg.exe" + }; + + argv_printf(&a, "%s %s %s %s", args[0], args[1], args[2], args[3]); + assert_int_equal(a.argc, 4); + for (i = 0; i < a.argc; i++) + { + assert_string_equal(a.argv[i], args[i]); + } + + argv_free(&a); +} + static void argv_parse_cmd__command_string__argc_correct(void **state) { @@ -237,6 +259,7 @@ main(void) cmocka_unit_test(argv_printf__group_sep_in_arg__fail_no_ouput), cmocka_unit_test(argv_printf__combined_path_with_spaces__argc_correct), cmocka_unit_test(argv_printf__empty_parameter__argc_correct), + cmocka_unit_test(argv_printf__long_args__data_correct), cmocka_unit_test(argv_parse_cmd__command_string__argc_correct), cmocka_unit_test(argv_parse_cmd__command_and_extra_options__argc_correct), cmocka_unit_test(argv_printf_cat__used_twice__argc_correct),