bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

printf functions without INT_MAX limitation


From: Bruno Haible
Subject: printf functions without INT_MAX limitation
Date: Sun, 21 Apr 2024 18:27:11 +0200

Hi Paul,

In several places, we have hit the possibility that the *printf functions
fails with EOVERFLOW (due to a result larger than INT_MAX characters):

  - While trying to avoid analyzer warnings from xasprintf(). [1]

  - IIRC, you also wrote that in coreutils you would prefer to 'printf'
    a variant that doesn't fail if a string happens to be larger than 2 GiB.

I would propose to solve this in three steps:

1) Ensure that vasnprintf() has no INT_MAX limit built-in.
   I think, this means doing the %s processing inside of vasnprintf, instead
   of using snprintf for this directive. vasnprintf.o becomes a little bit
   bigger.

2) Introduce variants of *printf functions, that return a 'ptrdiff_t' instead
   of 'int'. (For results longer than PTRDIFF_MAX, they will fail with error
   ENOMEM, not EOVERFLOW.) This gives rise to several new gnulib modules.

   A sketch of the new module dependencies is as follows ("->" denoting a
   module dependency):

     c-snprintf -> c-zsnprintf
     c-zsnprintf -> c-vasnprintf
     c-vasprintf -> c-vazsprintf
     c-vazsprintf -> c-vasnprintf
     c-vsnprintf -> c-vzsnprintf
     c-vzsnprintf -> c-vasnprintf
     c-xvasprintf -> c-vazsprintf
     dprintf -> dzprintf
     dzprintf -> vasnprintf
     fprintf -> fzprintf
     fzprintf -> vasnprintf
     obstack-printf -> obstack-zprintf
     obstack-zprintf -> vasnzprintf
     printf -> zprintf
     zprintf -> vfzprintf
     snprintf -> zsnprintf
     zsnprintf -> vasnprintf
     sprintf -> zsprintf
     zsprintf -> vasnprintf
     vasnwprintf -> vazsnwprintf
     vasprintf -> vazsprintf
     vazsprintf -> vasnprintf
     vdprintf -> vdzprintf
     vdzprintf -> vasnprintf
     vfprintf -> vfzprintf
     vfzprintf -> vasnprintf
     vprintf -> vzprintf
     vzprintf -> vfzprintf
     vsnprintf -> vzsnprintf
     vzsnprintf -> vasnprintf
     vsprintf -> vzsprintf
     vzsprintf -> vasnprintf
     xprintf -> zprintf
     xvasprintf -> vazsprintf

   and likewise for *printf-posix module variants.

3) Make use of these variants in coreutils etc.

What do you think?

     Bruno


PS: Regarding the letter 'z': I originally wanted to use the letter 'l',
but codesearch.debian.net tells me that 'lprintf' is already widely used,
with the meaning of printing a message to a log file. These are the
statistics for use of <?>printf:

  a    1200
  b    2300
  c    1800
  d   33400
  e   19900
  f 1876600
  g    2400
  h     500
  i    2200
  j       5
  k    1100
  l   12300
  m   18900
  n     900
  o    4500
  p    4500
  q     700
  r    2100
  s  559100
  t   13300
  u     800
  v   11300
  w    4700
  x    8400
  y      32
  z     300

In order to avoid conflicts with existing code and existing libraries,
a prefix needs to be picked that is little used so far. 'z' seems to fit.

[1] https://lists.gnu.org/archive/html/bug-gnulib/2023-06/msg00014.html






reply via email to

[Prev in Thread] Current Thread [Next in Thread]