Re: [PATCH v9 2/9] lib: vsprintf: export simple_strntoull() in a safe prototype
From: Rodrigo Alencar
Date: Fri Mar 27 2026 - 11:17:23 EST
On 26/03/27 12:21PM, Andy Shevchenko wrote:
> On Fri, Mar 27, 2026 at 10:11:56AM +0000, Rodrigo Alencar wrote:
> > On 26/03/27 11:17AM, Andy Shevchenko wrote:
> > > On Fri, Mar 27, 2026 at 09:45:17AM +0100, Petr Mladek wrote:
> > > > On Fri 2026-03-20 16:27:27, Rodrigo Alencar via B4 Relay wrote:
>
> ...
>
> > > > > +extern ssize_t __must_check simple_strntoull(const char *startp, const char **endp,
> > > > > + unsigned int base, size_t max_chars,
> > > > > + unsigned long long *res);
> > > >
> > > > Sigh, naming is hard. I personally find it a bit confusing that the
> > > > name is too similar to the unsafe API.
> > > >
> > > > IMHO, the semantic of the new API is closer to kstrtoull().
> > > > It just limits the size, so I would call it kstrntoull().
> > >
> > > It's not. kstrto*() quite strict about the input, this one is actually relaxed
> > > variant, so I wouldn't mix these two groups.
> > >
> > > > Also I would use int as the return parameter, see below.
>
> ...
>
> > > TBH, I am skeptical about this approach. My main objection is max_chars
> > > parameter. If we want to limit the input strictly to the given number of
> > > characters, we have to copy the string and then just use kstrto*() in a normal
> > > way. The whole idea of that parameter is to be able to parse the fractional
> > > part of the float number as 'iiiii.fffff', where 'i' is for integer part, and
> > > 'f' for the fractional. Since we have *endp, we may simply check that.
> >
> > A max_chars would not be only useful for that. It can prevent out-of-bounds
> > reads when the input isn't NUL-terminated (like buffers, file chunks,
> > network packets, memory-mapped data, ....). Even if there is a NUL later in
> > memory, a regular strtoull() function may consume characters that are outside
> > the field one intends to parse.
>
> Okay, but is it the current case or just an attempt to solve the problem that
> doesn't exist (yet)?
The current case can be seen as such. Copying the string and use regular ksrto*()
requires an unecessary scan of string from the user side, which is something that
_parse_integer_limit() already does, mostly because it checks for digits and stops
at any non-digit character. In the IIO case, we also want control over the consumed
characters because there are weird terminations like "dB", so having an implementation
like this ends up with a cleaner sequence of steps.
> > > In case if we want to parse only, say, 6 digits and input is longer there are
> > > a few options (in my personal preferences, the first is the better):
> > > - consider the input invalid
> > > - parse it as is up to the maximum and then do ceil() or floor() on top of that
> > > - copy only necessary amount of the (sub)string and parse that.
> >
> > Yes, my use case is the fixed point parsing, but I suppose we are implementing
> > things here for reuse.
>
> Yes, I'm full for reuse, but I want to have it balanced between complexity,
> existing use cases and possible reuse in the future.
Not seeing complexity here as in this case I am just exposing something
that already exists! No need for a completely different implementation.
I just want to get an agreement on the naming and interface prototype.
Bringing back the discussion again just because I suppose Petr havent even
seen the v8 of this patch series. If kstrtox.h is the right place for this,
kstrntoull() sounds like ideal. Specially because simple_strto*() is already
labeled as unsafe and kstrnto*() != kstrto*().
> > Also, the default behavior of the previous fixed point
> > parsing in IIO is flooring the result, which leads to the same result as
> > ignoring further digits.
>
> Correct, I also lean to implying floor() (as you can read below).
>
> > > The problem with precision is that we need to also consider floor() or ceil()
> > > and I don't think this should be burden of the library as it's individual
> > > preference of each of the callers (users). At least for the starter, we will
> > > see if it's only one approach is used, we may incorporate it into the library
> > > code.
> > >
> > > The easiest way out is to just consider the input invalid if it overflows the
> > > given type (s32 or s64).
> > >
> > > But we need to have an agreement what will be the representation of the
> > > fixed-width float numbers in the kernel? Currently IIO uses
> > > struct float // name is crafted for simplicity
> > > {
> > > int integer;
> > > int fraction;
> > > }
> >
> > Yes, but to represent things like that, an assumption is made to the precision that
> > "fraction" carries.
>
> Correct.
>
> > > This parser wants AFAIU to have at the end of the day something like
> > >
> > > struct float
> > > {
> > > s64 integer;
> > > s64 fraction;
> > > }
> > >
> > > but also wants to have the fraction part be limited in some cases to s32
> > > or so:
> > >
> > > struct float
> > > {
> > > s64 integer;
> > > s32 fraction; // precision may be lost if input is longer
> > > }
> > >
> > > Maybe we want to have kstrtof32() and kstrtof64() for these two cases?
> > >
> > > With that we will always consider the fraction part as 32- or 64-bit,
> > > imply floor() on the fraction for the sake of simplicity and require
> > > it to be NUL-terminated with possible trailing '\n'.
> >
> > I think this is a good idea, but calling it float or fixed point itself
> > is a bit confusing as float often refers to the IEEE 754 standard and
> > fixed point types is often expressed in Q-format.
>
> Yeah... I am lack of better naming.
decimals is the name, but they are often represented as:
DECIMAL = INT * 10^X + FRAC
in a single 64-bit number, which would be fine for my end use case.
However IIO decimal fixed point parsing is out there for quite some time a
lot of drivers use that. The interface often relies on breaking parsed values
into an integer array (for standard attributes int val and int val2 are expected).
--
Kind regards,
Rodrigo Alencar