diff --git a/Include/Python.h b/Include/Python.h --- a/Include/Python.h +++ b/Include/Python.h @@ -123,6 +123,7 @@ #include "eval.h" #include "pyctype.h" +#include "pymemsets.h" #include "pystrtod.h" #include "pystrcmp.h" #include "dtoa.h" diff --git a/Makefile.pre.in b/Makefile.pre.in --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -350,6 +350,7 @@ Python/importdl.o \ Python/marshal.o \ Python/modsupport.o \ + Python/mymemsets.o \ Python/mystrtoul.o \ Python/mysnprintf.o \ Python/peephole.o \ @@ -819,6 +820,7 @@ $(srcdir)/Include/pyerrors.h \ $(srcdir)/Include/pyfpe.h \ $(srcdir)/Include/pymath.h \ + $(srcdir)/Include/pymemsets.h \ $(srcdir)/Include/pygetopt.h \ $(srcdir)/Include/pymacro.h \ $(srcdir)/Include/pymem.h \ diff --git a/Modules/_sha3/sha3module.c b/Modules/_sha3/sha3module.c --- a/Modules/_sha3/sha3module.c +++ b/Modules/_sha3/sha3module.c @@ -150,7 +150,8 @@ #define SHA3_process Update #define SHA3_done Final #define SHA3_copystate(dest, src) memcpy(&(dest), &(src), sizeof(SHA3_state)) -#define SHA3_clearstate(state) memset(&(state), 0, sizeof(SHA3_state)) +#define SHA3_clearstate(state) _Py_memset_s(&(state), sizeof(SHA3_state),\ + 0, sizeof(SHA3_state)) /* The structure for storing SHA3 info */ diff --git a/Modules/sha1module.c b/Modules/sha1module.c --- a/Modules/sha1module.c +++ b/Modules/sha1module.c @@ -301,9 +301,11 @@ /* Internal methods for a hash object */ static void -SHA1_dealloc(PyObject *ptr) +SHA1_dealloc(SHA1object *self) { - PyObject_Del(ptr); + _Py_memset_s(&(self->hash_state), sizeof(struct sha1_state), + 0, sizeof(struct sha1_state)); + PyObject_Del(self); } @@ -443,7 +445,7 @@ sizeof(SHA1object), /*tp_size*/ 0, /*tp_itemsize*/ /* methods */ - SHA1_dealloc, /*tp_dealloc*/ + (destructor)SHA1_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -425,6 +425,7 @@ + @@ -638,6 +639,7 @@ + diff --git a/Python/pythonrun.c b/Python/pythonrun.c --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -97,6 +97,9 @@ extern void _PyGILState_Fini(void); #endif /* WITH_THREAD */ +/* Hack to force loading of mymemset.o */ +errno_t (*_Py_memset_s_hack)(void*, rsize_t, int, rsize_t) = _Py_memset_s; + int Py_DebugFlag; /* Needed by parser.c */ int Py_VerboseFlag; /* Needed by import.c */ int Py_QuietFlag; /* Needed by sysmodule.c */ diff --git a/configure b/configure --- a/configure +++ b/configure @@ -10459,6 +10459,32 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for memset_s" >&5 +$as_echo_n "checking for memset_s... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ +char buf[10]; memset_s(buf, sizeof(buf), 0, sizeof(buf)); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + +$as_echo "#define HAVE_MEMSET_S 1" >>confdefs.h + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking for epoll" >&5 $as_echo_n "checking for epoll... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext diff --git a/configure.ac b/configure.ac --- a/configure.ac +++ b/configure.ac @@ -2872,6 +2872,13 @@ AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) ]) +AC_MSG_CHECKING(for memset_s) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[char buf[10]; memset_s(buf, sizeof(buf), 0, sizeof(buf))]])], + [AC_DEFINE(HAVE_MEMSET_S, 1, Define if you have the C11 'memset_s' function.) + AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) +]) AC_MSG_CHECKING(for epoll) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[void *x=epoll_create]])], [AC_DEFINE(HAVE_EPOLL, 1, Define if you have the 'epoll' functions.) diff --git a/pyconfig.h.in b/pyconfig.h.in --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -549,6 +549,9 @@ /* Define to 1 if you have the `memrchr' function. */ #undef HAVE_MEMRCHR +/* Define if you have the C11 'memset_s' function. */ +#undef HAVE_MEMSET_S + /* Define to 1 if you have the `mkdirat' function. */ #undef HAVE_MKDIRAT