From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753620AbcBVRv7 (ORCPT ); Mon, 22 Feb 2016 12:51:59 -0500 Received: from mx1.redhat.com ([209.132.183.28]:41293 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751937AbcBVRv5 (ORCPT ); Mon, 22 Feb 2016 12:51:57 -0500 Date: Mon, 22 Feb 2016 12:51:54 -0500 From: Jessica Yu To: Andy Shevchenko Cc: Andrew Morton , Rasmus Villemoes , Kees Cook , linux-kernel@vger.kernel.org Subject: Re: sscanf: implement basic character sets Message-ID: <20160222175154.GA31460@packer-debian-8-amd64.digitalocean.com> References: <1455931322-27170-1-git-send-email-jeyu@redhat.com> <1456136021.13244.21.camel@linux.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1; format=flowed Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <1456136021.13244.21.camel@linux.intel.com> X-OS: Linux eisen.io 3.16.0-4-amd64 x86_64 User-Agent: Mutt/1.5.23 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org +++ Andy Shevchenko [22/02/16 12:13 +0200]: >On Fri, 2016-02-19 at 20:22 -0500, Jessica Yu wrote: >> Implement basic character sets for the '%[]' conversion specifier. >> >> The '%[]' conversion specifier matches a nonempty sequence of >> characters >> from the specified set of accepted (or with '^', rejected) characters >> between the brackets. The substring matched is to be made up of >> characters >> in (or not in) the set. This implementation differs from its glibc >> counterpart in that it does not support character ranges (e.g., 'a-z' >> or >> '0-9'), the hyphen '-' is *not* a special character, and the brackets >> themselves cannot be matched. >> >> Signed-off-by: Jessica Yu >> --- >>  lib/vsprintf.c | 35 +++++++++++++++++++++++++++++++++++ >>  1 file changed, 35 insertions(+) >> >> diff --git a/lib/vsprintf.c b/lib/vsprintf.c >> index 525c8e1..6ee3e7f 100644 >> --- a/lib/vsprintf.c >> +++ b/lib/vsprintf.c >> @@ -2714,6 +2714,41 @@ int vsscanf(const char *buf, const char *fmt, >> va_list args) >>   num++; >>   } >>   continue; >> + case '[': >> + { >> + char *s = (char *)va_arg(args, char *); >> + char set[U8_MAX] = { 0 }; > >Hmm... 255 on stack, not the best idea. > >> + size_t (*op)(const char *str, const char >> *set); >> + size_t len = 0; >> + bool negate = (*(fmt) == '^'); >> + >> + if (field_width == -1) >> + field_width = SHRT_MAX; >> + >> + op = negate ? &strcspn : &strspn; >> + if (negate) >> + fmt++; >> + >> + len = strcspn(fmt, "]"); >> + /* invalid format; stop here */ >> + if (!len) >> + return num; >> + >> + strncpy(set, fmt, len); > >Perhaps here you may allocate memory on heap and copy the given set. >IIRC kstrndup() does this. Thanks for the comments Andy. I did in fact use kstrndup() originally, but I was not sure about error handling. i.e., if kstrndup() fails we normally return -ENOMEM, but in this case I suppose sscanf() could just fail and return num? Thanks, Jessica