You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
On macOS with Xcode 14 we now get warnings like these:
Objects/unicodeobject.c:736:16: warning: 'sprintf' is deprecated: This function is provided for compatibility reasons only. Due to security concerns inherent in the design of sprintf(3), it is highly recommended that you use snprintf(3) instead. [-Wdeprecated-declarations]
While we can prove to ourselves that these specific sprintf() calls are safe, the warnings are annoying, but disabling them would also disable other, more useful warnings (or so @Yhg1s tells me on Discord). So let's just switch these to snprintf().
Supported builds of Python 3.5+ on Windows use Visual Studio 2015+ and the Universal C Runtime (UCRT), for which snprintf() and vsnprintf() conform to C99. In Python 3.9+, "Include/pyerrors.h" no longer defines these two functions as macros that call non-standard _snprintf() and _vsnprintf().
PyOS_vsnprintf() in "Python/mysnprintf.c" was apparently overlooked when "pyerrors.h" was updated. It should have been modified to always call vsnprintf(). Also, all PyOS_snprintf() and PyOS_vsnprintf() calls can be replaced with snprintf() and vsnprintf().
I've tried to compile CPython with explicit -Wdeprecated-declarations set in PY_STDMODULE_CFLAGS and got no warnings. However, sprintf() is still widely used:
» ag 'sprintf\('
Misc/HISTORY
24555: the standard sprintf() and vsprintf() C lib APIs, these versions
33626:similar to sprintf() in C. The right argument is either a single
33627:value or a tuple of values. All features of Standard C sprintf() are
Python/flowgraph.c
276: sprintf(arg, "arg: %d ", i->i_oparg);
279: sprintf(arg, "target: %p [%d] ", i->i_target, i->i_oparg);
Python/pystrtod.c
1204: exp_len = sprintf(p, "%+.02d", exp);
Python/specialize.c
368: sprintf(buf, "%s%s.txt", dirname, hex_name);
Objects/typeobject.c
5591: sprintf(msg, "type_traverse() called on non-heap type '%.100s'",
Objects/unicodeobject.c
789: size = sprintf(str, "&#%d;", PyUnicode_READ(kind, data, i));
2596: sprintf(buffer, fmt, va_arg(*vargs, long)) :
2597: sprintf(buffer, fmt, va_arg(*vargs, unsigned long));
2601: sprintf(buffer, fmt, va_arg(*vargs, long long)) :
2602: sprintf(buffer, fmt, va_arg(*vargs, unsigned long long));
2606: sprintf(buffer, fmt, va_arg(*vargs, Py_ssize_t)) :
2607: sprintf(buffer, fmt, va_arg(*vargs, size_t));
2610: len = sprintf(buffer, fmt, va_arg(*vargs, ptrdiff_t));
2614: sprintf(buffer, fmt, va_arg(*vargs, intmax_t)) :
2615: sprintf(buffer, fmt, va_arg(*vargs, uintmax_t));
2619: sprintf(buffer, fmt, va_arg(*vargs, int)) :
2620: sprintf(buffer, fmt, va_arg(*vargs, unsigned int));
2672: len = sprintf(number, "%p", va_arg(*vargs, void*));
8358: sprintf(buffer, "&#%d;", (int)PyUnicode_READ_CHAR(unicode, collpos));
Objects/bytesobject.c
269: sprintf(buffer, "%ld", va_arg(vargs, long));
272: sprintf(buffer, "%zd", va_arg(vargs, Py_ssize_t));
275: sprintf(buffer, "%d", va_arg(vargs, int));
283: sprintf(buffer, "%lu", va_arg(vargs, unsigned long));
286: sprintf(buffer, "%zu", va_arg(vargs, size_t));
289: sprintf(buffer, "%u", va_arg(vargs, unsigned int));
296: sprintf(buffer, "%i", va_arg(vargs, int));
302: sprintf(buffer, "%x", va_arg(vargs, int));
328: sprintf(buffer, "%p", va_arg(vargs, void*));
564:/* fmt%(v1,v2,...) is roughly equivalent to sprintf(fmt, v1, v2, ...) */
Parser/string_parser.c
134: sprintf(p, "\\U%08x", chr);
Programs/_freeze_module.c
124: sprintf(filename, "<frozen %s>", name);
Modules/_testexternalinspection.c
234: sprintf(maps_file_path, "/proc/%d/maps", pid);
Modules/_pickle.c
2110: sprintf(pdata, "%c%ld\n", INT, val);
Modules/unicodedata.c
1329: sprintf(buffer, "CJK UNIFIED IDEOGRAPH-%X", code);
Modules/_testcapimodule.c
991: sprintf(buffer, "%s module: \"%s\" attribute: \"%s\"", \
Modules/getnameinfo.c
142: sprintf(numserv, "%d", ntohs(port));
Modules/_datetimemodule.c
1629: sprintf(freplacement, "%06d", TIME_GET_MICROSECOND(object));
1631: sprintf(freplacement, "%06d", DATE_GET_MICROSECOND(object));
1633: sprintf(freplacement, "%06d", 0);
Modules/_ctypes/stgdict.c
651: sprintf(buf, "%s:%s:", fieldfmt, fieldname);
Modules/_ctypes/_ctypes.c
398: sprintf(buf, "%zd,", shape[k]);
400: sprintf(buf, "%zd)", shape[k]);
2538: cp += sprintf(cp, "%x", Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
2547: cp += sprintf(cp, ":%x", Py_SAFE_DOWNCAST(target->b_index, Py_ssize_t, int));
3269: sprintf(mangled_name, "_%s@%d", name, i*4);
4768: sprintf(name, "%.200s_Array_%Id",
4771: sprintf(name, "%.200s_Array_%ld",
Well, we risk that when the next version your toolchain of choice is updated, the warnings will reappear. IMO we might as well fix them. @sobolevn's PR was a good start, but only needed to be split in more manageable chunks.
Activity
terryjreedy commentedon Feb 8, 2023
There are 49 hits in our .c code + some in externals.
pythongh-101703: use `snprintf` instead of `sprintf`
pythongh-101703: use `snprintf` instead of `sprintf`
serhiy-storchaka commentedon Feb 9, 2023
Interesting, there were issues with portability of
snprintf(on Windows) in the past. I hope they were fixed in last 20 years.erlend-aasland commentedon Feb 9, 2023
CC. @eryksun
eryksun commentedon Feb 9, 2023
Supported builds of Python 3.5+ on Windows use Visual Studio 2015+ and the Universal C Runtime (UCRT), for which
snprintf()andvsnprintf()conform to C99. In Python 3.9+, "Include/pyerrors.h" no longer defines these two functions as macros that call non-standard_snprintf()and_vsnprintf().PyOS_vsnprintf()in "Python/mysnprintf.c" was apparently overlooked when "pyerrors.h" was updated. It should have been modified to always callvsnprintf(). Also, allPyOS_snprintf()andPyOS_vsnprintf()calls can be replaced withsnprintf()andvsnprintf().terryjreedy commentedon Apr 24, 2023
I closed #103733 as duplicate of this.
gvanrossum commentedon Mar 19, 2024
@terryjreedy @sobolevn Can this be closed? I haven't seen those warnings in a while, though I see plenty of sprintf() calls in the code still.
terryjreedy commentedon Mar 20, 2024
I have no involvement with C code, so fine with me. @serhiy-storchaka ?
sobolevn commentedon Mar 20, 2024
I've tried to compile CPython with explicit
-Wdeprecated-declarationsset inPY_STDMODULE_CFLAGSand got no warnings. However,sprintf()is still widely used:Not sure why this warning is gone.
erlend-aasland commentedon Mar 20, 2024
Well, we risk that when the next version your toolchain of choice is updated, the warnings will reappear. IMO we might as well fix them. @sobolevn's PR was a good start, but only needed to be split in more manageable chunks.
sobolevn commentedon Mar 20, 2024
I can redo some parts of it, there were rather easy. I'll start with them today.