From: Alejandro Colomar <alx+linux-hardening@kernel.org>
To: Joe Perches <joe@perches.com>
Cc: Alejandro Colomar <alx@kernel.org>,
linux-hardening@vger.kernel.org,
Krzysztof Kozlowski <krzk@kernel.org>,
"Maciej W. Rozycki" <macro@orcam.me.uk>,
Geert Uytterhoeven <geert@linux-m68k.org>,
Andreas Schwab <schwab@linux-m68k.org>,
Andy Shevchenko <andy@kernel.org>,
Bartosz Golaszewski <brgl@kernel.org>,
Daniel Scally <djrscally@gmail.com>,
Danilo Krummrich <dakr@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Hans Verkuil <hverkuil-cisco@xs4all.nl>,
Heikki Krogerus <heikki.krogerus@linux.intel.com>,
Johan Hovold <johan@kernel.org>, Kees Cook <kees@kernel.org>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
Len Brown <lenb@kernel.org>,
Linus Torvalds <torvalds@linux-foundation.org>,
Linus Walleij <linusw@kernel.org>,
Namhyung Kim <namhyung@kernel.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
Rob Herring <robh@kernel.org>,
Sakari Ailus <sakari.ailus@linux.intel.com>,
Saravana Kannan <saravanak@kernel.org>,
Steven Rostedt <rostedt@goodmis.org>,
Tom Zanussi <zanussi@kernel.org>,
linux-acpi@vger.kernel.org, driver-core@lists.linux.dev,
linux-kernel@vger.kernel.org, devicetree@vger.kernel.org,
linux-gpio@vger.kernel.org,
Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Subject: Re: [PATCH v6 02/19] string: Add strprefix()
Date: Sat, 14 Nov 2026 17:59:18 +0100 [thread overview]
Message-ID: <aviOPo6bZ-WGsndf@devuan> (raw)
In-Reply-To: <c113f651d1ce1b2d42ab9d0c59ae5a0cd17ddb6a.camel@perches.com>
[-- Attachment #1: Type: text/plain, Size: 4651 bytes --]
Hi Joe,
> Date: 2026-11-14 07:53:25-0800
> From: Joe Perches <joe@perches.com>
>
[...]
> > +/**
> > + * strprefix - string prefix
> > + * @s: The string to be tested
> > + * @prefix: The string to see if @s starts with
> > + *
> > + * A common way to test a prefix of a string is to do:
> > + * strncmp(s, 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 strprefix().
> > + *
> > + * Returns:
> > + * * @s + strlen(@prefix) if @s starts with @prefix
> > + * * NULL if @s does not start with @prefix
> > + */
> > +__attribute__((nonnull(1, 2)))
>
> __nonnull_args(1, 2)
Thanks!
> A negative of this is that it implies the return should
> always be tested even though it can be known that the
> return is effectively bool.
I'm not sure I follow. The attribute is about the arguments, not the
return value. Perhaps I don't understand what you mean by "this".
>
> Also the block
>
> > + * A common way to test a prefix of a string is to do:
> > + * strncmp(s, prefix, sizeof(prefix) - 1)
>
> IMO isn't useful
I tend to agree. I think that is just one example of code this API
replaces, but there are many more. I think I'd prefer a description of
the API, without comparing it to existing patterns (because there might
be too many).
> and the description doesn't say what happens
> when prefix is an empty string (which IMO should match).
It doesn't, because the general behavior naturally extends to that
extreme. That is, it's the non-surprising result.
For any non-empty prefix, the function succeeds if all the non-null
characters from the prefix are found sequentially at the begining of the
string. In other words, it matches if and only if strstr(s,prefix)==s.
For the empty prefix, it still behaves like that. If all the non-null
characters from the prefix are found sequentially at the begining of the
string, it succeeds. This always happens, of course, so strprefix(s,"")
always succeeds. Similarly, strstr(s,"")==s.
Since there's nothing different, I don't see a strong reason to document
it at all. And that's also the reason why I think the issue in
str_has_prefix() is not just a different design decision, but rather
a bug. If the name of str_has_prefix() had been strprefix_len() --which
BTW, I'm tempted to rename in this patch set--, then it would be just a
design decision, as it would behave correctly for what the name implies,
and it would be an incorrect use if one tries to use it for determining
whether a strings starts with a possibly-empty prefix or not. But the
function is called str_has_prefix(), which implies a boolean behavior,
and that boolean behavior is wrong for the case of the empty string.
That is, while any string starts with an empty string, str_has_prefix()
returns false, and that is wrong.
> And the name strprefix could be confused with a function
> that actually prefixes a string to another string.
This would be a stretch. <string.h> functions, with the exception of
the *dup() functions, do not allocate memory. They're a collection of
functions that only perform byte operations on strings, or in general,
on character arrays.
Prefixing a string to another string would require either knowing the
size of the buffer (and thus have a size_t parameter), or allocate new
memory. Since this function doesn't have a size_t, the former can be
ruled out. And allocating memory would be very weird, so we can also
discard that.
> maybe strprefixed or str_is_prefixed ?
strprefixed() might be okay-ish. I still prefer strprefix(), because
common sense can rule those interpretations out, and also because it's
widely implemented with that name.
> And these are all candidates for converted uses to
> whatever is the function name or steq:
>
> $ git grep -P '[^w]strncmp\s*\(\s*[\w\.\-\>\s]*,\s*\"\w*"\s*,\s*\d+\s*\)' -- '*.[ch]' | wc -l
> 946
Yup, there's a lot of code that could be converted. For now, I find it
more pressing to transform the existing calls to strstarts(), and as
many of str_has_prefix() as reasonable, to minimize drift, but I can
also work later on converting the strncmp(3) calls.
> [^w] because of prom_strncmp
Since there's no anchor before the 's', that doesn't change anything:
$ git grep -P '[^w]strncmp\s*\(\s*[\w\.\-\>\s]*,\s*\"\w*"\s*,\s*\d+\s*\)' -- '*.[ch]' | wc -l
946
$ git grep -P 'strncmp\s*\(\s*[\w\.\-\>\s]*,\s*\"\w*"\s*,\s*\d+\s*\)' -- '*.[ch]' | wc -l
946
>
--
<https://www.alejandro-colomar.es>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2026-11-14 16:59 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-14 15:21 [PATCH v6 00/19] Add strprefix() and fix a bug with it Alejandro Colomar
2026-11-14 15:21 ` [PATCH v6 01/19] string: Add streq() Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 02/19] string: Add strprefix() Alejandro Colomar
2026-11-14 15:28 ` Joe Perches
2026-11-14 17:03 ` Alejandro Colomar
2026-11-14 15:53 ` Joe Perches
2026-11-14 16:59 ` Alejandro Colomar [this message]
2026-11-14 15:22 ` [PATCH v6 03/19] string: Document corner-case misbehavior in str_has_prefix() for empty prefix Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 04/19] device property: Fix fwnode_name_eq() for empty node names Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 05/19] stddef: Add const_cast() Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 06/19] string: Add [C]QChar_of() and QVoid_of() Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 07/19] string: Make strprefix() const-qualifier-generic Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 08/19] perf map: Use bool for return type instead of int Alejandro Colomar
2026-11-14 15:22 ` [PATCH v6 09/19] string: Make strstarts() a legacy alias for strprefix() Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 10/19] platform/x86: hp-bioscfg: Rename local variable Alejandro Colomar
2026-11-14 16:04 ` Joe Perches
2026-11-14 17:08 ` Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 11/19] treewide: s/strstarts/strprefix/g Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 12/19] string: Remove strstarts() Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 13/19] s390/test_unwind: Use bool for booleans Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 14/19] treewide: Replace boolean uses of str_has_prefix() by strprefix() Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 15/19] treewide: Replace some " Alejandro Colomar
2026-11-14 15:23 ` [PATCH v6 16/19] string: Add strsuffix() Alejandro Colomar
2026-11-14 15:24 ` [PATCH v6 17/19] string: Make strends() a legacy alias for strsuffix() Alejandro Colomar
2026-11-14 15:24 ` [PATCH v6 18/19] treewide: s/\<strends\>/strsuffix/g Alejandro Colomar
2026-11-14 15:24 ` [PATCH v6 19/19] string: Remove strends() Alejandro Colomar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aviOPo6bZ-WGsndf@devuan \
--to=alx+linux-hardening@kernel.org \
--cc=alx@kernel.org \
--cc=andy@kernel.org \
--cc=bartosz.golaszewski@oss.qualcomm.com \
--cc=brgl@kernel.org \
--cc=dakr@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=djrscally@gmail.com \
--cc=driver-core@lists.linux.dev \
--cc=geert@linux-m68k.org \
--cc=gregkh@linuxfoundation.org \
--cc=heikki.krogerus@linux.intel.com \
--cc=hverkuil-cisco@xs4all.nl \
--cc=joe@perches.com \
--cc=johan@kernel.org \
--cc=kees@kernel.org \
--cc=krzk@kernel.org \
--cc=laurent.pinchart@ideasonboard.com \
--cc=lenb@kernel.org \
--cc=linusw@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=macro@orcam.me.uk \
--cc=namhyung@kernel.org \
--cc=rafael@kernel.org \
--cc=robh@kernel.org \
--cc=rostedt@goodmis.org \
--cc=sakari.ailus@linux.intel.com \
--cc=saravanak@kernel.org \
--cc=schwab@linux-m68k.org \
--cc=torvalds@linux-foundation.org \
--cc=zanussi@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox