[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
- printf functions without INT_MAX limitation,
Bruno Haible <=
- Re: printf functions without INT_MAX limitation, Paul Eggert, 2024/04/21
- Re: printf functions without INT_MAX limitation, Bruno Haible, 2024/04/21
- Re: printf functions without INT_MAX limitation, Paul Eggert, 2024/04/22
- Re: printf functions without INT_MAX limitation, Bruno Haible, 2024/04/22
- Re: printf functions without INT_MAX limitation, Paul Eggert, 2024/04/24
- Re: printf functions without INT_MAX limitation, Bruno Haible, 2024/04/27
- Re: printf functions without INT_MAX limitation, Bruno Haible, 2024/04/27