public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* printf_arginfo_size_function error handling
@ 2021-03-24 16:39 Alejandro Colomar (man-pages)
  2021-03-24 19:30 ` Alejandro Colomar (man-pages)
  0 siblings, 1 reply; 3+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-03-24 16:39 UTC (permalink / raw)
  To: GNU C Library

Hi,

I've been re-reading the docs for printf_register_specifier(), and
there's something in an example code that doesn't make much sense:

<https://www.gnu.org/software/libc/manual/html_node/Printf-Extension-Example.html>
[[

int
print_widget_arginfo (const struct printf_info *info, size_t n,
                      int *argtypes)
{
  /* We always take exactly one argument and this is a pointer to the
     structure.. */
  if (n > 0)
    argtypes[0] = PA_POINTER;
  return 1;
}

]]

In the code above there is a check that n>0, but:

What can a user do if n<=0 ?  There's no error reporting method, is there?
And, is it possible for such a case to happen?  What to do there?

I think either using an assert() or not checking at all might make more
sense (depending on how possible is n<=0 to happen).  The current check
continues as if everything was fine, just without setting argtypes[0],
so if there's an error, it will be carried to some future stage, where
nasal daemons might unexpectedly happen.

Thanks,

Alex

-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: printf_arginfo_size_function error handling
  2021-03-24 16:39 printf_arginfo_size_function error handling Alejandro Colomar (man-pages)
@ 2021-03-24 19:30 ` Alejandro Colomar (man-pages)
  2021-03-24 19:39   ` Alejandro Colomar (man-pages)
  0 siblings, 1 reply; 3+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-03-24 19:30 UTC (permalink / raw)
  To: GNU C Library

Hi,

On 3/24/21 5:39 PM, Alejandro Colomar (man-pages) wrote:
> Hi,
> 
> I've been re-reading the docs for printf_register_specifier(), and
> there's something in an example code that doesn't make much sense:
> 
> <https://www.gnu.org/software/libc/manual/html_node/Printf-Extension-Example.html>
> [[
> 
> int
> print_widget_arginfo (const struct printf_info *info, size_t n,
>                       int *argtypes)
> {
>   /* We always take exactly one argument and this is a pointer to the
>      structure.. */
>   if (n > 0)
>     argtypes[0] = PA_POINTER;
>   return 1;
> }
> 
> ]]
> 
> In the code above there is a check that n>0, but:
> 
> What can a user do if n<=0 ?  There's no error reporting method, is there?
> And, is it possible for such a case to happen?  What to do there?
> 
> I think either using an assert() or not checking at all might make more
> sense (depending on how possible is n<=0 to happen).  The current check
> continues as if everything was fine, just without setting argtypes[0],
> so if there's an error, it will be carried to some future stage, where
> nasal daemons might unexpectedly happen.

After reading the sources, I see a few things:

- There's an undocumented error handling mechanism:  you can return a
negative value to signify an error.  However, I couldn't understand what
exactly happens when you report an error.  Does the printf_function get
called?

- n seems to be nonnegative:  it's called in three places
(<stdio-common/vfprintf-internal.c:1821>,
<stdio-common/printf-parsemb.c:316>, and stdio-common/printf-prs.c:94),
and all of them make sure n is positive, so the test in the example is
useless.

- I could't understand how n>1 could be used from reading the
(obfuscated) sources.  And there's no documentation.  Is it really
supported?  And how?  Would you mind documenting that?  Maybe with an
example that makes use of the non-obvious features of this API.

- Even though printf_arginfo_size_function supposedly handles the case
of n>1, printf_function doesn't seem to handle it.  It gets the array of
arguments, but it doesn't get the size of the array, so the only valid
assumption is that the array is of size 1; anything else might fail
silently.  If you use the misterious feature of multiple arguments for a
single specifier, how do you guarantee that you'll receive as many slots
in the array as you want?  By checking it in the arginfo function and
reporting an error if n is not big enough?  Will that guarantee that
printf_function is not called?  Again, I see no documentation at all
about this, and the sources are not the easiest to read.

Thanks,

Alex

-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: printf_arginfo_size_function error handling
  2021-03-24 19:30 ` Alejandro Colomar (man-pages)
@ 2021-03-24 19:39   ` Alejandro Colomar (man-pages)
  0 siblings, 0 replies; 3+ messages in thread
From: Alejandro Colomar (man-pages) @ 2021-03-24 19:39 UTC (permalink / raw)
  To: GNU C Library

Hi,

On 3/24/21 8:30 PM, Alejandro Colomar (man-pages) wrote:
> Hi,
> 
> On 3/24/21 5:39 PM, Alejandro Colomar (man-pages) wrote:
>> Hi,
>>
>> I've been re-reading the docs for printf_register_specifier(), and
>> there's something in an example code that doesn't make much sense:
>>
>> <https://www.gnu.org/software/libc/manual/html_node/Printf-Extension-Example.html>
>> [[
>>
>> int
>> print_widget_arginfo (const struct printf_info *info, size_t n,
>>                       int *argtypes)
>> {
>>   /* We always take exactly one argument and this is a pointer to the
>>      structure.. */
>>   if (n > 0)
>>     argtypes[0] = PA_POINTER;
>>   return 1;
>> }
>>
>> ]]
>>
>> In the code above there is a check that n>0, but:
>>
>> What can a user do if n<=0 ?  There's no error reporting method, is there?
>> And, is it possible for such a case to happen?  What to do there?
>>
>> I think either using an assert() or not checking at all might make more
>> sense (depending on how possible is n<=0 to happen).  The current check
>> continues as if everything was fine, just without setting argtypes[0],
>> so if there's an error, it will be carried to some future stage, where
>> nasal daemons might unexpectedly happen.
> 
> After reading the sources, I see a few things:
> 
> - There's an undocumented error handling mechanism:  you can return a
> negative value to signify an error.  However, I couldn't understand what
> exactly happens when you report an error.  Does the printf_function get
> called?
> 
> - n seems to be nonnegative:  it's called in three places
> (<stdio-common/vfprintf-internal.c:1821>,
> <stdio-common/printf-parsemb.c:316>, and stdio-common/printf-prs.c:94),
> and all of them make sure n is positive, so the test in the example is
> useless.
> 
> - I could't understand how n>1 could be used from reading the
> (obfuscated) sources.  And there's no documentation.  Is it really
> supported?  And how?  Would you mind documenting that?  Maybe with an
> example that makes use of the non-obvious features of this API.
> 
> - Even though printf_arginfo_size_function supposedly handles the case
> of n>1, printf_function doesn't seem to handle it.  It gets the array of
> arguments, but it doesn't get the size of the array, so the only valid
> assumption is that the array is of size 1; anything else might fail
> silently.  If you use the misterious feature of multiple arguments for a
> single specifier, how do you guarantee that you'll receive as many slots
> in the array as you want?  By checking it in the arginfo function and
> reporting an error if n is not big enough?  Will that guarantee that
> printf_function is not called?  Again, I see no documentation at all
> about this, and the sources are not the easiest to read.
> 

If I understood correctly, the 3rd parameter argtypes of
printf_arginfo_size_function is an array, right?

So a more friendly prototype would be

typedef
int printf_arginfo_size_function(const struct printf_info *info,
                                 size_t n,
                                 int argtypes[static n],
                                 int *size);

Also, what about the last 'size' argument of
printf_arginfo_size_function?  Is it an array or just a pointer?  If
it's a pointer, how do you pass the size of each of the arguments you
set in argtypes?  Is the following prototype correct (I'm guessing)?:

typedef
int printf_arginfo_size_function(const struct printf_info *info,
                                 size_t n,
                                 int argtypes[static n],
                                 int size[static n]);

Thanks,

Alex

-- 
Alejandro Colomar
Linux man-pages comaintainer; https://www.kernel.org/doc/man-pages/
http://www.alejandro-colomar.es/

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-03-24 19:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-24 16:39 printf_arginfo_size_function error handling Alejandro Colomar (man-pages)
2021-03-24 19:30 ` Alejandro Colomar (man-pages)
2021-03-24 19:39   ` Alejandro Colomar (man-pages)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).