[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: best way to deal with macOS deprecation of sprintf?
From: |
Bruno Haible |
Subject: |
Re: best way to deal with macOS deprecation of sprintf? |
Date: |
Thu, 03 Nov 2022 22:47:48 +0100 |
Paul Eggert wrote:
> As noted in <https://bugs.gnu.org/58966>, macOS 13.0 has deprecated
> sprintf, on the grounds that buffer overflow happens too often with it.
> As a result, compilers will complain about any calls to sprintf, even if
> you don't configure with --enable-gcc-warnings. I assume vsprintf is
> similar.
>
> This macOS change runs afoul of common practice in Gnulib and Gnu
> programs, which is to allocate a buffer of appropriate size and then
> sprintf into it.
>
> Here are some ways we can respond to Apple's deprecation of sprintf.
In the long run, I am hoping that fortifying declarations in glibc,
in combination with advances in GCC and clang (e.g. regarding
__builtin_dynamic_object_size [1][2]) will lead to a situation where
- most sprintf calls can be verified as OK by the compiler,
- the remaining sprintf calls produce compiler warnings.
I understand that we are not there yet.
[1] https://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html
[2] https://gcc.gnu.org/gcc-12/changes.html
> 0. Do nothing. That's what we did when Microsoft deprecated sprintf in
> 2005 (in favor of sprintf_s), and the world rolled along much as it did
> before.
>
> 1. Stop using sprintf in Gnulib and Gnu apps. I'm not inclined to do
> this, as it's makework and is likely to introduce bugs; plus, it's a tad
> slower.
>
> 2a. Add a Gnulib module sprintf-pacify that puts a "#pragma GCC
> diagnostic ignored "-Wdeprecated-declarations"' in Gnulib's stdio.h if
> that pacifies a false alarm about sprintf. Have sprintf-posix depend on
> this new module. Something like this in gnulib/lib/stdio.h, perhaps:
>
> #if @PACIFY_SPRINTF_DEPRECATION@
> # pragma GCC diagnostic push
> # pragma GCC diagnostic ignored "-Wdeprecated-declarations"
> int
> gl_vsprintf (char *restrict str, char const *restrict fmt, va_list ap)
> {
> return vsprintf (str, fmt, ap);
> }
> int
> gl_sprintf (char *restrict str, char const *restrict fmt, ...)
> {
> va_list ap;
> va_start (ap, format);
> int n = vsprintf (str, format, ap);
> va_end (ap);
> return n;
> }
> # pragma GCC diagnostic pop
> # define sprintf gl_sprintf
> # define vsprintf gl_vsprintf
> #endif
>
> 2b. Like (2a), but simply put -Wno-deprecated-declarations in CFLAGS
> instead of into gnulib's lib/stdio.h.
>
> 3. Don't bother with a new module; simply add the functionality to the
> existing sprintf-posix module.
The various GNU packages have different requirements regarding whether
they want 'sprintf-posix' or not. And they have different policies whether
warnings on macOS can be tolerated or need to be eliminated. And the two
are unrelated.
I would therefore favour (2a), modified to be orthogonal to the
sprintf-posix module. I.e. the user can request sprintf-pacify or
sprintf-posix or both.
> #if @PACIFY_SPRINTF_DEPRECATION@
This should probably use a Gnulib module indicator:
#if @GNULIB_SPRINTF_PACIFY@ && (defined __APPLE__ && defined __MACH__)
Bruno