Subject: Re: Invalid timezone (tzalloc failure) treated as out-of-memory

From: Paul Eggert <[email-masked]>
Date: Sun, 11 Mar 2018 00:33:03 -0800

[resending, I hope to the right place this time]

Thanks for reporting the problem. I have installed the attached two patches,
which I think should fix the problem so I'm closing the bug report. Please give
them a try on NetBSD (as I typically don't use NetBSD).

>From f7c07930b581b1bcfdfb1874b6883233516bdf11 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Tue, 16 May 2017 14:19:36 -0700
Subject: [PATCH] Fix minor timezone memory leak

* src/editfns.c (wall_clock_tz): Remove; unused.
---
 src/editfns.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/src/editfns.c b/src/editfns.c
index ecb8e3f083..75eb75a729 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -81,10 +81,8 @@ static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool);
 
 enum { tzeqlen = sizeof "TZ=" - 1 };
 
-/* Time zones equivalent to current local time, to wall clock time,
-   and to UTC, respectively.  */
+/* Time zones equivalent to current local time and to UTC, respectively.  */
 static timezone_t local_tz;
-static timezone_t wall_clock_tz;
 static timezone_t const utc_tz = 0;
 
 /* The cached value of Vsystem_name.  This is used only to compare it
@@ -269,7 +267,6 @@ init_editfns (bool dumping)
 
   /* Set the time zone rule now, so that the call to putenv is done
      before multiple threads are active.  */
-  wall_clock_tz = xtzalloc (0);
   tzlookup (tz ? build_string (tz) : Qwall, true);
 
   pw = getpwuid (getuid ());
-- 
2.14.3

>From 46844ad78968cd804d0e5fc98ce49b46b3d8a53d Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sun, 11 Mar 2018 00:18:34 -0800
Subject: [PATCH] Port to NetBSD tzalloc

Problem reported by Valery Ushakov (Bug#30738).
* src/editfns.c (xtzalloc): Remove.
(invalid_time_zone_specification): New function.
(tzlookup): Port to NetBSD, where tzalloc can fail when the TZ
string has an invalid value.
---
 src/editfns.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/src/editfns.c b/src/editfns.c
index 3a34dd0980..debe10572d 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -117,14 +117,10 @@ emacs_mktime_z (timezone_t tz, struct tm *tm)
   return t;
 }
 
-/* Allocate a timezone, signaling on failure.  */
-static timezone_t
-xtzalloc (char const *name)
+static _Noreturn void
+invalid_time_zone_specification (Lisp_Object zone)
 {
-  timezone_t tz = tzalloc (name);
-  if (!tz)
-    memory_full (SIZE_MAX);
-  return tz;
+  xsignal2 (Qerror, build_string ("Invalid time zone specification"), zone);
 }
 
 /* Free a timezone, except do not free the time zone for local time.
@@ -205,9 +201,15 @@ tzlookup (Lisp_Object zone, bool settz)
 	    }
 	}
       else
-	xsignal2 (Qerror, build_string ("Invalid time zone specification"),
-		  zone);
-      new_tz = xtzalloc (zone_string);
+	invalid_time_zone_specification (zone);
+
+      new_tz = tzalloc (zone_string);
+      if (!new_tz)
+	{
+	  if (errno == ENOMEM)
+	    memory_full (SIZE_MAX);
+	  invalid_time_zone_specification (zone);
+	}
     }
 
   if (settz)
-- 
2.14.3