Issue #12839: Fix crash in zlib module due to version mismatch.

If the version of zlib used to compile the zlib module is incompatible
with the one that is actually linked in, then calls into zlib will fail.
This can leave attributes of the z_stream uninitialized, so we must take
care to avoid segfaulting by trying to use an invalid pointer.

Fix by Richard M. Tew.
diff --git a/Misc/ACKS b/Misc/ACKS
index cdae287..e728c51 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -813,6 +813,7 @@
 Amy Taylor
 Anatoly Techtonik
 Mikhail Terekhov
+Richard M. Tew
 Tobias Thelen
 James Thomas
 Robin Thomas
diff --git a/Misc/NEWS b/Misc/NEWS
index e7faa4e..3709142 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -40,6 +40,9 @@
 Library
 -------
 
+- Issue #12839: Fix crash in zlib module due to version mismatch.
+  Fix by Richard M. Tew.
+
 - Issue #12786: Set communication pipes used by subprocess.Popen CLOEXEC to
   avoid them being inherited by other subprocesses.
 
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
index bd6d6e2..035aa8e 100644
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -72,7 +72,13 @@
 static void
 zlib_error(z_stream zst, int err, char *msg)
 {
-    const char *zmsg = zst.msg;
+    const char *zmsg = Z_NULL;
+    /* In case of a version mismatch, zst.msg won't be initialized.
+       Check for this case first, before looking at zst.msg. */
+    if (err == Z_VERSION_ERROR)
+        zmsg = "library version mismatch";
+    if (zmsg == Z_NULL)
+        zmsg = zst.msg;
     if (zmsg == Z_NULL) {
         switch (err) {
         case Z_BUF_ERROR: