mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	bpo-36020: Remove snprintf macro in pyerrors.h (GH-20889)
On Windows, GH-include "pyerrors.h" no longer defines "snprintf" and
"vsnprintf" macros.
PyOS_snprintf() and PyOS_vsnprintf() should be used to get portable
behavior.
Replace snprintf() calls with PyOS_snprintf() and replace vsnprintf()
calls with PyOS_vsnprintf().
(cherry picked from commit e822e37946)
Co-authored-by: Victor Stinner <vstinner@python.org>
			
			
This commit is contained in:
		
							parent
							
								
									9a0624a3d9
								
							
						
					
					
						commit
						b498c7f1b3
					
				
					 6 changed files with 27 additions and 32 deletions
				
			
		|  | @ -4,6 +4,8 @@ | ||||||
| extern "C" { | extern "C" { | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
|  | #include <stdarg.h>               // va_list | ||||||
|  | 
 | ||||||
| /* Error handling definitions */ | /* Error handling definitions */ | ||||||
| 
 | 
 | ||||||
| PyAPI_FUNC(void) PyErr_SetNone(PyObject *); | PyAPI_FUNC(void) PyErr_SetNone(PyObject *); | ||||||
|  | @ -307,21 +309,6 @@ PyAPI_FUNC(int) PyUnicodeTranslateError_SetReason( | ||||||
|     const char *reason          /* UTF-8 encoded string */ |     const char *reason          /* UTF-8 encoded string */ | ||||||
|     ); |     ); | ||||||
| 
 | 
 | ||||||
| /* These APIs aren't really part of the error implementation, but
 |  | ||||||
|    often needed to format error messages; the native C lib APIs are |  | ||||||
|    not available on all platforms, which is why we provide emulations |  | ||||||
|    for those platforms in Python/mysnprintf.c, |  | ||||||
|    WARNING:  The return value of snprintf varies across platforms; do |  | ||||||
|    not rely on any particular behavior; eventually the C99 defn may |  | ||||||
|    be reliable. |  | ||||||
| */ |  | ||||||
| #if defined(MS_WIN32) && !defined(HAVE_SNPRINTF) |  | ||||||
| # define HAVE_SNPRINTF |  | ||||||
| # define snprintf _snprintf |  | ||||||
| # define vsnprintf _vsnprintf |  | ||||||
| #endif |  | ||||||
| 
 |  | ||||||
| #include <stdarg.h> |  | ||||||
| PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char  *format, ...) | PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char  *format, ...) | ||||||
|                         Py_GCC_ATTRIBUTE((format(printf, 3, 4))); |                         Py_GCC_ATTRIBUTE((format(printf, 3, 4))); | ||||||
| PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va) | PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va) | ||||||
|  |  | ||||||
|  | @ -0,0 +1,2 @@ | ||||||
|  | On Windows, ``#include "pyerrors.h"`` no longer defines ``snprintf`` and | ||||||
|  | ``vsnprintf`` macros. | ||||||
|  | @ -84,7 +84,7 @@ PrintError(const char *msg, ...) | ||||||
|     va_list marker; |     va_list marker; | ||||||
| 
 | 
 | ||||||
|     va_start(marker, msg); |     va_start(marker, msg); | ||||||
|     vsnprintf(buf, sizeof(buf), msg, marker); |     PyOS_vsnprintf(buf, sizeof(buf), msg, marker); | ||||||
|     va_end(marker); |     va_end(marker); | ||||||
|     if (f != NULL && f != Py_None) |     if (f != NULL && f != Py_None) | ||||||
|         PyFile_WriteString(buf, f); |         PyFile_WriteString(buf, f); | ||||||
|  |  | ||||||
|  | @ -473,13 +473,12 @@ remove_unusable_flags(PyObject *m) | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifdef MS_WIN32 | #ifdef MS_WIN32 | ||||||
| #undef EAFNOSUPPORT | #  undef EAFNOSUPPORT | ||||||
| #define EAFNOSUPPORT WSAEAFNOSUPPORT | #  define EAFNOSUPPORT WSAEAFNOSUPPORT | ||||||
| #define snprintf _snprintf |  | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifndef SOCKETCLOSE | #ifndef SOCKETCLOSE | ||||||
| #define SOCKETCLOSE close | #  define SOCKETCLOSE close | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #if (defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)) && !defined(__NetBSD__) && !defined(__DragonFly__) | #if (defined(HAVE_BLUETOOTH_H) || defined(HAVE_BLUETOOTH_BLUETOOTH_H)) && !defined(__NetBSD__) && !defined(__DragonFly__) | ||||||
|  |  | ||||||
|  | @ -1133,7 +1133,7 @@ verify_identifier(struct tok_state *tok) | ||||||
|         Py_DECREF(s); |         Py_DECREF(s); | ||||||
|         // PyUnicode_FromFormatV() does not support %X
 |         // PyUnicode_FromFormatV() does not support %X
 | ||||||
|         char hex[9]; |         char hex[9]; | ||||||
|         snprintf(hex, sizeof(hex), "%04X", ch); |         (void)PyOS_snprintf(hex, sizeof(hex), "%04X", ch); | ||||||
|         if (Py_UNICODE_ISPRINTABLE(ch)) { |         if (Py_UNICODE_ISPRINTABLE(ch)) { | ||||||
|             syntaxerror(tok, "invalid character '%c' (U+%s)", ch, hex); |             syntaxerror(tok, "invalid character '%c' (U+%s)", ch, hex); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,8 @@ | ||||||
| #include "Python.h" | #include "Python.h" | ||||||
| 
 | 
 | ||||||
| /* snprintf() wrappers.  If the platform has vsnprintf, we use it, else we
 | /* snprintf() and vsnprintf() wrappers.
 | ||||||
|  | 
 | ||||||
|  |    If the platform has vsnprintf, we use it, else we | ||||||
|    emulate it in a half-hearted way.  Even if the platform has it, we wrap |    emulate it in a half-hearted way.  Even if the platform has it, we wrap | ||||||
|    it because platforms differ in what vsnprintf does in case the buffer |    it because platforms differ in what vsnprintf does in case the buffer | ||||||
|    is too small:  C99 behavior is to return the number of characters that |    is too small:  C99 behavior is to return the number of characters that | ||||||
|  | @ -52,16 +54,17 @@ PyOS_snprintf(char *str, size_t size, const  char  *format, ...) | ||||||
| int | int | ||||||
| PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va) | PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va) | ||||||
| { | { | ||||||
|     int len;  /* # bytes written, excluding \0 */ |  | ||||||
| #ifdef HAVE_SNPRINTF |  | ||||||
| #define _PyOS_vsnprintf_EXTRA_SPACE 1 |  | ||||||
| #else |  | ||||||
| #define _PyOS_vsnprintf_EXTRA_SPACE 512 |  | ||||||
|     char *buffer; |  | ||||||
| #endif |  | ||||||
|     assert(str != NULL); |     assert(str != NULL); | ||||||
|     assert(size > 0); |     assert(size > 0); | ||||||
|     assert(format != NULL); |     assert(format != NULL); | ||||||
|  | 
 | ||||||
|  |     int len;  /* # bytes written, excluding \0 */ | ||||||
|  | #if defined(_MSC_VER) || defined(HAVE_SNPRINTF) | ||||||
|  | #  define _PyOS_vsnprintf_EXTRA_SPACE 1 | ||||||
|  | #else | ||||||
|  | #  define _PyOS_vsnprintf_EXTRA_SPACE 512 | ||||||
|  |     char *buffer; | ||||||
|  | #endif | ||||||
|     /* We take a size_t as input but return an int.  Sanity check
 |     /* We take a size_t as input but return an int.  Sanity check
 | ||||||
|      * our input so that it won't cause an overflow in the |      * our input so that it won't cause an overflow in the | ||||||
|      * vsnprintf return value or the buffer malloc size.  */ |      * vsnprintf return value or the buffer malloc size.  */ | ||||||
|  | @ -70,10 +73,12 @@ PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va) | ||||||
|         goto Done; |         goto Done; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| #ifdef HAVE_SNPRINTF | #if defined(_MSC_VER) | ||||||
|  |     len = _vsnprintf(str, size, format, va); | ||||||
|  | #elif defined(HAVE_SNPRINTF) | ||||||
|     len = vsnprintf(str, size, format, va); |     len = vsnprintf(str, size, format, va); | ||||||
| #else | #else | ||||||
|     /* Emulate it. */ |     /* Emulate vsnprintf(). */ | ||||||
|     buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE); |     buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE); | ||||||
|     if (buffer == NULL) { |     if (buffer == NULL) { | ||||||
|         len = -666; |         len = -666; | ||||||
|  | @ -96,9 +101,11 @@ PyOS_vsnprintf(char *str, size_t size, const char  *format, va_list va) | ||||||
|     } |     } | ||||||
|     PyMem_FREE(buffer); |     PyMem_FREE(buffer); | ||||||
| #endif | #endif | ||||||
|  | 
 | ||||||
| Done: | Done: | ||||||
|     if (size > 0) |     if (size > 0) { | ||||||
|         str[size-1] = '\0'; |         str[size-1] = '\0'; | ||||||
|  |     } | ||||||
|     return len; |     return len; | ||||||
| #undef _PyOS_vsnprintf_EXTRA_SPACE | #undef _PyOS_vsnprintf_EXTRA_SPACE | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Miss Islington (bot)
						Miss Islington (bot)