Bug#848721: apt: please make the moo reproducible

Chris Lamb lamby at debian.org
Mon Dec 19 19:57:57 UTC 2016


Source: apt
Version: 1.4~beta2
Severity: wishlist
Tags: patch
User: reproducible-builds at lists.alioth.debian.org
Usertags: timestamps randomness
X-Debbugs-Cc: reproducible-bugs at lists.alioth.debian.org

Hi,

Whilst working on the Reproducible Builds effort [0], we noticed
that apt could not moo reproducibly.

Patch attached.

 [0] https://reproducible-builds.org/


Regards,

-- 
      ,''`.
     : :'  :     Chris Lamb
     `. `'`      lamby at debian.org / chris-lamb.co.uk
       `-
-------------- next part --------------
diff --git a/apt-private/private-moo.cc b/apt-private/private-moo.cc
index a879991..d55df8a 100644
--- a/apt-private/private-moo.cc
+++ b/apt-private/private-moo.cc
@@ -15,6 +15,7 @@
 
 #include <apt-private/private-moo.h>
 #include <apt-private/private-output.h>
+#include <apt-private/private-utils.h>
 
 #include <stddef.h>
 #include <string.h>
@@ -27,7 +28,7 @@
 									/*}}}*/
 
 static std::string getMooLine() {					/*{{{*/
-   time_t const timenow = time(NULL);
+   time_t const timenow = GetTimeNow();
    struct tm special;
    localtime_r(&timenow, &special);
    enum { NORMAL, PACKAGEMANAGER, APPRECIATION, AGITATION, AIRBORN } line;
@@ -163,7 +164,8 @@ bool DoMooApril(CommandLine &)						/*{{{*/
 									/*}}}*/
 bool DoMoo(CommandLine &CmdL)						/*{{{*/
 {
-   time_t const timenow = time(NULL);
+   const time_t timenow = GetTimeNow();
+
    struct tm april;
    localtime_r(&timenow, &april);
    if (april.tm_mday == 1 && april.tm_mon == 3)
diff --git a/apt-private/private-utils.cc b/apt-private/private-utils.cc
index 775bf7e..64eb23d 100644
--- a/apt-private/private-utils.cc
+++ b/apt-private/private-utils.cc
@@ -1,11 +1,15 @@
 #include <config.h>
 
 #include <apt-pkg/configuration.h>
+#include <apt-pkg/error.h>
 #include <apt-pkg/fileutl.h>
 
 #include <apt-private/private-utils.h>
 
 #include <cstdlib>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
 #include <unistd.h>
 
 // DisplayFileInPager - Display File with pager				/*{{{*/
@@ -74,3 +78,32 @@ bool EditFileInSensibleEditor(std::string const &filename)
    return ExecWait(Process, "editor", false);
 }
 									/*}}}*/
+time_t GetTimeNow()						/*{{{*/
+{
+   const char *source_date_epoch = getenv("SOURCE_DATE_EPOCH");
+
+   if (!source_date_epoch) {
+      return time(NULL);
+   }
+
+   errno = 0;
+   char *endptr;
+   const unsigned long long epoch = strtoull(source_date_epoch, &endptr, 10);
+
+   if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0))
+         || (errno != 0 && epoch == 0)) {
+      _error->Error("SOURCE_DATE_EPOCH: strtoull: %s\n", strerror(errno));
+   }
+   if (endptr == source_date_epoch) {
+      _error->Error("SOURCE_DATE_EPOCH: No digits were found: %s\n", endptr);
+   }
+   if (*endptr != '\0') {
+       _error->Error("SOURCE_DATE_EPOCH: Trailing garbage: %s\n", endptr);
+   }
+   if (epoch > ULONG_MAX) {
+      _error->Error("SOURCE_DATE_EPOCH: %llu must be <= %lu", epoch, ULONG_MAX);
+   }
+
+   return (time_t) epoch;
+}
+									/*}}}*/
diff --git a/apt-private/private-utils.h b/apt-private/private-utils.h
index b3b2496..2024777 100644
--- a/apt-private/private-utils.h
+++ b/apt-private/private-utils.h
@@ -5,5 +5,6 @@
 
 bool DisplayFileInPager(std::string const &filename);
 bool EditFileInSensibleEditor(std::string const &filename);
+time_t GetTimeNow();
 
 #endif


More information about the Reproducible-bugs mailing list