[38/59] Avoid a malloc in __tzfile_read

Message ID 20250105055750.1668721-39-eggert@cs.ucla.edu (mailing list archive)
State New
Headers
Series time: sync mktime from Gnulib |

Checks

Context Check Description
redhat-pt-bot/TryBot-apply_patch success Patch applied to master at the time it was sent

Commit Message

Paul Eggert Jan. 5, 2025, 5:57 a.m. UTC
  * time/tzfile.c (__tzfile_read): Avoid a malloc in the usual case,
by reusing a stack buffer.
---
 time/tzfile.c | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)
  

Patch

diff --git a/time/tzfile.c b/time/tzfile.c
index 8efe5b2ec9..09ebc7d8ea 100644
--- a/time/tzfile.c
+++ b/time/tzfile.c
@@ -143,7 +143,7 @@  __tzfile_read (const char *file)
   static const char default_tzdir[] = TZDIR "/";
   tzidx isstdcnt, isutcnt;
   FILE *f;
-  union { struct tzhead tzhead; tzidx tzidx_aligned; } u;
+  union { struct tzhead tzhead; tzidx tzidx_aligned; char tzfilename[64]; } u;
   tzidx charcnt;
   tzidx i;
   int trans_width = 4;
@@ -180,13 +180,20 @@  __tzfile_read (const char *file)
       size_t tzdirlen = strlen (tzdir);
       tzdirlen -= tzdir[tzdirlen - 1] == '/';
       size_t filelen = strlen (file);
-      new = malloc (tzdirlen + 1 + filelen + 1);
-      if (new == NULL)
-	goto ret_free_transitions;
-      char *newp = __mempcpy (new, tzdir, tzdirlen);
-      *newp++ = '/';
-      __mempcpy (newp, file, filelen + 1);
-      file = new;
+      size_t absfile_size = tzdirlen + 1 + filelen + 1;
+      char *absfile;
+      if (absfile_size <= sizeof u.tzfilename)
+	absfile = u.tzfilename;
+      else
+	{
+	  absfile = new = malloc (absfile_size);
+	  if (absfile == NULL)
+	    goto ret_free_transitions;
+	}
+      char *p = __mempcpy (absfile, tzdir, tzdirlen);
+      *p++ = '/';
+      __mempcpy (p, file, filelen + 1);
+      file = absfile;
     }
 
   /* If we were already using tzfile, check whether the file changed.  */