@@ -2060,105 +2060,75 @@ zlib_getattr(PyObject *self, PyObject *args)
20602060 return NULL ;
20612061}
20622062
2063- PyDoc_STRVAR (zlib_version__doc__ ,
2063+ PyDoc_STRVAR (zlib_version_info__doc__ ,
20642064"zlib.zlib_version_info\n\
20652065\n\
20662066Zlib version information as a named tuple." );
20672067
2068- static PyStructSequence_Field zlib_version_fields [] = {
2068+ static PyStructSequence_Field zlib_version_info_fields [] = {
20692069 {"major" , "Major release number" },
20702070 {"minor" , "Minor release number" },
20712071 {"revision" , "Revision release number" },
20722072 {"subversion" , "Subversion release number" },
20732073 {0 }
20742074};
20752075
2076- static PyStructSequence_Desc zlib_version_desc = {
2077- "zlib.zlib_version_info" , /* name */
2078- zlib_version__doc__ , /* doc */
2079- zlib_version_fields , /* fields */
2076+ static PyStructSequence_Desc zlib_version_info_desc = {
2077+ "zlib.zlib_version_info" , /* name */
2078+ zlib_version_info__doc__ , /* doc */
2079+ zlib_version_info_fields , /* fields */
20802080 4
20812081};
20822082
2083- static PyObject *
2084- make_zlib_version (PyTypeObject * type , const char * string )
2085- {
2086- PyObject * version ;
2087- int pos = 0 ;
2088- unsigned int major = 0 , minor = 0 , revision = 0 , subversion = 0 ;
2089-
2090- sscanf (string , "%u.%u.%u.%u" , & major , & minor , & revision , & subversion );
2091-
2092- version = PyStructSequence_New (type );
2093- if (version == NULL ) {
2094- return NULL ;
2095- }
2096-
2097- #define SetIntItem (VALUE ) \
2098- PyStructSequence_SET_ITEM(version, pos++, PyLong_FromUnsignedLong(VALUE)); \
2099- if (PyErr_Occurred()) { \
2100- Py_DECREF(version); \
2101- return NULL; \
2102- }
2103-
2104- SetIntItem (major )
2105- SetIntItem (minor )
2106- SetIntItem (revision )
2107- SetIntItem (subversion )
2108- #undef SetIntItem
2109-
2110- return version ;
2111- }
2112-
21132083#ifdef ZLIBNG_VERSION
2114- PyDoc_STRVAR (zlibng_version__doc__ ,
2084+ PyDoc_STRVAR (zlibng_version_info__doc__ ,
21152085"zlib.zlibng_version_info\n\
21162086\n\
21172087Zlib-ng version information as a named tuple." );
21182088
2119- static PyStructSequence_Field zlibng_version_fields [] = {
2089+ static PyStructSequence_Field zlibng_version_info_fields [] = {
21202090 {"major" , "Major release number" },
21212091 {"minor" , "Minor release number" },
21222092 {"revision" , "Revision release number" },
21232093 {0 }
21242094};
21252095
2126- static PyStructSequence_Desc zlibng_version_desc = {
2127- "zlib.zlibng_version_info" , /* name */
2128- zlibng_version__doc__ , /* doc */
2129- zlibng_version_fields , /* fields */
2096+ static PyStructSequence_Desc zlibng_version_info_desc = {
2097+ "zlib.zlibng_version_info" , /* name */
2098+ zlibng_version_info__doc__ , /* doc */
2099+ zlibng_version_info_fields , /* fields */
21302100 3
21312101};
2102+ #endif // ZLIBNG_VERSION
21322103
2104+ /* Create a named tuple from the first *size* components of a version string
2105+ like "1.2.11" or "1.2.11.1". sscanf() is expected to fail on trailing
2106+ garbage and on versions with fewer components (for example "1.2.0.f" or
2107+ "1.3.1.zlib-ng"); the components which were not parsed are left zero.
2108+ This is deliberate -- a zero is more useful here than a hard error. */
21332109static PyObject *
2134- make_zlibng_version (PyTypeObject * type , const char * string )
2110+ make_version_info (PyTypeObject * type , const char * string , Py_ssize_t size )
21352111{
2136- PyObject * version ;
2137- int pos = 0 ;
2138- unsigned int major = 0 , minor = 0 , revision = 0 ;
2112+ unsigned int components [4 ] = {0 , 0 , 0 , 0 };
2113+ assert (size <= (Py_ssize_t )Py_ARRAY_LENGTH (components ));
21392114
2140- sscanf (string , "%u.%u.%u" , & major , & minor , & revision );
2115+ sscanf (string , "%u.%u.%u.%u" ,
2116+ & components [0 ], & components [1 ], & components [2 ], & components [3 ]);
21412117
2142- version = PyStructSequence_New (type );
2118+ PyObject * version = PyStructSequence_New (type );
21432119 if (version == NULL ) {
21442120 return NULL ;
21452121 }
2146-
2147- #define SetIntItem (VALUE ) \
2148- PyStructSequence_SET_ITEM(version, pos++, PyLong_FromUnsignedLong(VALUE)); \
2149- if (PyErr_Occurred()) { \
2150- Py_DECREF(version); \
2151- return NULL; \
2122+ for (Py_ssize_t i = 0 ; i < size ; i ++ ) {
2123+ PyObject * item = PyLong_FromUnsignedLong (components [i ]);
2124+ if (item == NULL ) {
2125+ Py_DECREF (version );
2126+ return NULL ;
2127+ }
2128+ PyStructSequence_SET_ITEM (version , i , item );
21522129 }
2153-
2154- SetIntItem (major )
2155- SetIntItem (minor )
2156- SetIntItem (revision )
2157- #undef SetIntItem
2158-
21592130 return version ;
21602131}
2161- #endif // ZLIBNG_VERSION
21622132
21632133
21642134static PyMethodDef zlib_methods [] =
@@ -2377,30 +2347,30 @@ zlib_exec(PyObject *mod)
23772347 }
23782348#endif
23792349 PyTypeObject * version_type ;
2380- version_type = PyStructSequence_NewType (& zlib_version_desc );
2350+ version_type = PyStructSequence_NewType (& zlib_version_info_desc );
23812351 if (version_type == NULL ) {
23822352 return -1 ;
23832353 }
23842354 if (PyModule_Add (mod , "ZLIB_VERSION_INFO" ,
2385- make_zlib_version (version_type , ZLIB_VERSION )) < 0 )
2355+ make_version_info (version_type , ZLIB_VERSION , 4 )) < 0 )
23862356 {
23872357 Py_DECREF (version_type );
23882358 return -1 ;
23892359 }
23902360 if (PyModule_Add (mod , "zlib_version_info" ,
2391- make_zlib_version (version_type , zlibVersion ())) < 0 )
2361+ make_version_info (version_type , zlibVersion (), 4 )) < 0 )
23922362 {
23932363 Py_DECREF (version_type );
23942364 return -1 ;
23952365 }
23962366 Py_DECREF (version_type );
23972367#ifdef ZLIBNG_VERSION
2398- version_type = PyStructSequence_NewType (& zlibng_version_desc );
2368+ version_type = PyStructSequence_NewType (& zlibng_version_info_desc );
23992369 if (version_type == NULL ) {
24002370 return -1 ;
24012371 }
24022372 if (PyModule_Add (mod , "ZLIBNG_VERSION_INFO" ,
2403- make_zlibng_version (version_type , ZLIBNG_VERSION )) < 0 )
2373+ make_version_info (version_type , ZLIBNG_VERSION , 3 )) < 0 )
24042374 {
24052375 Py_DECREF (version_type );
24062376 return -1 ;
0 commit comments