From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 75578 invoked by alias); 12 Oct 2016 13:14:12 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 75560 invoked by uid 89); 12 Oct 2016 13:14:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00,SPF_PASS autolearn=ham version=3.3.2 spammy=enhance, Enhance, strn*, 1827 X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 12 Oct 2016 13:14:01 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id E5628ABE4; Wed, 12 Oct 2016 13:13:58 +0000 (UTC) Subject: Re: [PATCH] Check \0-termination of string in c_getstr To: Richard Biener References: <678ff58e-4aa3-6145-f56b-780bf618338c@suse.cz> <1db7cd13-d403-9a6c-811a-bba82a35ef37@suse.cz> Cc: GCC Patches From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Message-ID: <9ab67f18-42a3-d66e-6777-b066f6d9af76@suse.cz> Date: Wed, 12 Oct 2016 13:14:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.2 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------F9DD16EB9D519BF7539AEF70" X-IsSubscribed: yes X-SW-Source: 2016-10/txt/msg00886.txt.bz2 This is a multi-part message in MIME format. --------------F9DD16EB9D519BF7539AEF70 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Content-length: 682 On 10/11/2016 12:28 PM, Richard Biener wrote: > On Tue, Oct 11, 2016 at 11:27 AM, Martin Liška wrote: >> As mentioned in the email that I reply to, c_getstr should check >> null termination of string constants. >> >> Tests of the whole series have been running. > > Looks ok to me (if testing passes). Thanks for the review, however I decided to enhance the API to support a requested length argument (if a string is not null terminated) and to return length of the string(usable for strn* functions folding). Patch can bootstrap on ppc64le-redhat-linux and survives regression tests as a whole series. Martin > > Thanks, > Richard. > >> Thanks, >> Martin --------------F9DD16EB9D519BF7539AEF70 Content-Type: text/x-patch; name="0002-Enhance-c_getstr-API.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0002-Enhance-c_getstr-API.patch" Content-length: 3290 >From e6c16ea038104ef15b087ff9fca23d9b2406e65e Mon Sep 17 00:00:00 2001 From: marxin Date: Mon, 10 Oct 2016 12:13:12 +0200 Subject: [PATCH] Enhance c_getstr API gcc/ChangeLog: 2016-10-10 Martin Liska * fold-const.c (c_getstr): Guard string termination, or validate that requested length is within a string constant. * fold-const.h (c_getstr): Set default value for the new arg. --- gcc/fold-const.c | 44 +++++++++++++++++++++++++++++++++++--------- gcc/fold-const.h | 3 ++- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 02aa484..eb53e84 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -14440,24 +14440,50 @@ fold_build_pointer_plus_hwi_loc (location_t loc, tree ptr, HOST_WIDE_INT off) } /* Return a char pointer for a C string if it is a string constant - or sum of string constant and integer constant. */ + or sum of string constant and integer constant. + If the string constant is properly zero-terminated, the constant is returned. + Otherwise, if REQ_LENGTH is a non-negative number, the constant + is returned if the string length is greater or equal to REQ_LENGTH. + If STRLEN is a valid pointer, length (including terminatinch character) + of returned string is stored to the argument. */ const char * -c_getstr (tree src) +c_getstr (tree src, HOST_WIDE_INT req_length, unsigned HOST_WIDE_INT *strlen) { tree offset_node; + if (strlen) + *strlen = 0; + src = string_constant (src, &offset_node); if (src == 0) - return 0; + return NULL; - if (offset_node == 0) - return TREE_STRING_POINTER (src); - else if (!tree_fits_uhwi_p (offset_node) - || compare_tree_int (offset_node, TREE_STRING_LENGTH (src) - 1) > 0) - return 0; + unsigned HOST_WIDE_INT offset = 0; + if (offset_node != NULL_TREE) + { + if (!tree_fits_uhwi_p (offset_node)) + return NULL; + else + offset = tree_to_uhwi (offset_node); + } - return TREE_STRING_POINTER (src) + tree_to_uhwi (offset_node); + unsigned HOST_WIDE_INT string_length = TREE_STRING_LENGTH (src); + const char *string = TREE_STRING_POINTER (src); + if (offset > string_length) + return NULL; + + /* If the string is properly '\0' character terminated, return it. */ + if ((string_length > 0 && string[string_length - 1] == 0) + || (req_length != -1 + && (unsigned HOST_WIDE_INT)req_length <= string_length - offset)) + { + if (strlen) + *strlen = string_length - offset; + return string + offset; + } + else + return NULL; } #if CHECKING_P diff --git a/gcc/fold-const.h b/gcc/fold-const.h index 637e46b..bbf831a 100644 --- a/gcc/fold-const.h +++ b/gcc/fold-const.h @@ -182,7 +182,8 @@ extern bool expr_not_equal_to (tree t, const wide_int &); extern tree const_unop (enum tree_code, tree, tree); extern tree const_binop (enum tree_code, tree, tree, tree); extern bool negate_mathfn_p (combined_fn); -extern const char *c_getstr (tree); +extern const char *c_getstr (tree src, HOST_WIDE_INT req_length = -1, + unsigned HOST_WIDE_INT *strlen = NULL); /* Return OFF converted to a pointer offset type suitable as offset for POINTER_PLUS_EXPR. Use location LOC for this conversion. */ -- 2.9.2 --------------F9DD16EB9D519BF7539AEF70--