Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp2525660imu; Sun, 23 Dec 2018 01:37:01 -0800 (PST) X-Google-Smtp-Source: ALg8bN7JTkHzBxpvkOPkbZew8xpcfH5b5+ymG90BghTUMMqLwv/b8MM+pdWApAKAGGe8QbqDIZz4 X-Received: by 2002:a63:6604:: with SMTP id a4mr8690896pgc.118.1545557821780; Sun, 23 Dec 2018 01:37:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545557821; cv=none; d=google.com; s=arc-20160816; b=r0zv21XbNVi1BjcD7I4wWnaBm+PNWRup0gMOvza9AknsVo2IQvSdRsvBTt5UkGMWjt aEmnA3hU+3ldK4hP+bvAhGkMzM6Rn1HNv8mVu/NJ2jz8p39atdWn0jZteWkAaMQZqpmB Z8xj2kWEW64BEadBg8L/qLW9qMMV6N5ecjdi3gfaOrd6Ky5mlPKvXsHIAKsEsmmEZH44 Om5a3mu1dtE82pqZpaNHP9Sg9+tlscvZVJ6yGCG4wK8svYLzPtpv+w00pgwObdHp74b/ CAbEFeoLspyNmTxCN/hz+YJ9CDmsVhObrq6XSZzpoKsCZMkmEs/uhOTPUc4JpZInmN3v IMBg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date; bh=DUat16hSDcgRtByHGoHBcgx5ymjil/5fRx1T27lv3p4=; b=Ub8z0yUBAnc5N+1HKhfHGHud0NwARNBzyZk1pATSPjUQEDx0AEl/QuMtoU9gR+jOE4 cDcTQygKSNhXMgewLgfSx9oFUSQtAs5X6eQlKtIzFE8Bt4wm62y0HvPuP08SxF3C/4Kd 2AWWYyD7toqRL5u4KvQ0DmJdzN3O9WIcc1/4wNEWd62WNyBHMB3Ip050+YRcHi9ZiElE uw+BduV8BwhRfWivhEa+8NtnIL+wRM0T2J6dTwXQTF9g/JcLW4gTM59xGlCf5Cm/b+rX t/FYbAQZm4BurNHuhngbZPole3PWHN83RMV2arF7gEgI1jgvUxWQo9NTL3KQ3eMZa+tt Zwyw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id x23si20513116pgj.247.2018.12.23.01.36.46; Sun, 23 Dec 2018 01:37:01 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2392191AbeLUWsU (ORCPT + 99 others); Fri, 21 Dec 2018 17:48:20 -0500 Received: from mail.kernel.org ([198.145.29.99]:41794 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725813AbeLUWsU (ORCPT ); Fri, 21 Dec 2018 17:48:20 -0500 Received: from gandalf.local.home (cpe-66-24-56-78.stny.res.rr.com [66.24.56.78]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 8AE3621928; Fri, 21 Dec 2018 22:48:18 +0000 (UTC) Date: Fri, 21 Dec 2018 17:48:16 -0500 From: Steven Rostedt To: Linus Torvalds Cc: Linux List Kernel Mailing , Ingo Molnar , Andrew Morton , Namhyung Kim , Masami Hiramatsu , Joe Perches , Tom Zanussi , Greg Kroah-Hartman Subject: Re: [for-next][PATCH 23/24] string.h: Add strncmp_prefix() helper macro Message-ID: <20181221174816.0ed7af47@gandalf.local.home> In-Reply-To: References: <20181221175618.968519903@goodmis.org> <20181221175659.208858193@goodmis.org> <20181221144054.20bdeb33@gandalf.local.home> <20181221153526.5e6055ca@gandalf.local.home> <20181221155513.11450ca6@gandalf.local.home> X-Mailer: Claws Mail 3.16.0 (GTK+ 2.24.32; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, 21 Dec 2018 14:08:11 -0800 Linus Torvalds wrote: > On Fri, Dec 21, 2018 at 12:55 PM Steven Rostedt wrote: > > > > On Fri, 21 Dec 2018 12:41:17 -0800 > > Linus Torvalds wrote: > > > > > Parentheses.... > > > > ? > > Your patch actually had them, but in the body of your email you did > > > #define have_prefix(str, prefix) ({ \ > > const char *__pfx = (const char *)prefix; \ > > which is just completely wrong. > > Considering your _old_ patch had the exact same bug, I really think > you need to start internalizing the whole "macro arguments *have* to > be properly protected" thing. Well, there's less with assignments that can go wrong than with other code. That is, there's little that can happen with "int x = arg;" where arg is the macro paramater to cause something really nasty. The chances of that happening is up there with using only two underscores causing an issue. But they don't hurt to add. > > And I agree with Joe that using a million underscores just makes code > less legible. Two underscores at the beginning is the standard > namespace protection. Underscores at the end do nothing. And using > *more* than two is just crazy. The two are standard for static variables in C code, but that makes me worry about macros. I usually do at least three for macros. The underscores at the end, to me, make it more balanced and easier to read: strncmp(str, ___prefix___, ___len___); To me looks better than: strncmp(str, ___prefix, ___len); But again, no reason to fight this bikeshed. > > Finally, I think the cast is actually bogus and wrong. Why would the > prefix ever be anything but "const char *"? Adding the cast only makes > it more possible that somebody uses a truly wrong type ("unsigned long > *" ?), and then the cast just silently hides it. Actually after I sent the email, I was thinking the same thing, that the original strncmp() would probably complain about that too, and we should keep it the same. Not sure why I even suggested that. Perhaps, I tested too many use cases :-/ > > If somebody uses "unsigned char *" for this, they'd get the exact same > warning if they were using strncmp and do this by hand. > > So why would that helper function act any differently? Particularly > when it then has the huge downside that it will also accept absolute > garbage? > > Anyway, that was a long and winding NAK for your patch. But after all that and said. I tested it as a static __always_inline, and guess what. It also optimizes out the strlen() for constants!!! Suggested-by: Andreas Schwab -- Steve diff --git a/include/linux/string.h b/include/linux/string.h index 27d0482e5e05..538469dfb458 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -456,4 +456,25 @@ static inline void memcpy_and_pad(void *dest, size_t dest_len, memcpy(dest, src, dest_len); } +/** + * str_has_prefix - Test if a string has a given prefix + * @str: The string to test + * @prefix: The string to see if @str starts with + * + * A common way to test a prefix of a string is to do: + * strncmp(str, prefix, sizeof(prefix) - 1) + * + * But this can lead to bugs due to typos, or if prefix is a pointer + * and not a constant. Instead use str_has_prefix(). + * + * Returns: 0 if @str does not start with @prefix + strlen(@prefix) if @str does start with @prefix + */ +static __always_inline int str_has_prefix(const char *str, const char *prefix) +{ + int len = strlen(prefix); + + return strncmp(str, prefix, len) == 0 ? len : 0; +} + #endif /* _LINUX_STRING_H_ */