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