Source: colord
Version: 1.2.12-1
Severity: wishlist
Tags: patch
User: reproducible-bui...@lists.alioth.debian.org
Usertags: timestamps
Control: block -1 by 814883

Hi!

While working on the “reproducible builds” effort [1], we have noticed
that colord could not be built reproducibly.

The attached patches remove extra timestamps when generating CMF and
spectra and implement support for SOURCE_DATE_EPOCH. Together with a
patched lcms2, they make colord reproducible in our current experimental
framework.

 [1]: https://wiki.debian.org/ReproducibleBuilds

-- 
Lunar                                .''`. 
lu...@debian.org                    : :Ⓐ  :  # apt-get install anarchism
                                    `. `'` 
                                      `-   
From 97d54abbf3240a14b271ac7f8f79331adbf1a219 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Sat, 20 Feb 2016 12:48:47 +0100
Subject: [PATCH 1/2] Stop writing a CREATED header in CMF and spectra

For the same input `cd-it8 create-cmf` and `cd-it8 create-sp`
will create the exact same output except for the creation time.
As the header is optional and prevents CMF and spectra to be built
reproducibly, we use cd_it8_set_enable_created() to remove it
from the output.
---
 client/cd-it8.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/client/cd-it8.c b/client/cd-it8.c
index 987776a..26bc26d 100644
--- a/client/cd-it8.c
+++ b/client/cd-it8.c
@@ -303,6 +303,7 @@ cd_util_create_cmf (CdUtilPrivate *priv,
 	if (dot != NULL)
 		*dot = '\0';
 	cd_it8_set_title (cmf, title);
+	cd_it8_set_enable_created (cmf, FALSE);
 
 	/* save */
 	file = g_file_new_for_path (values[0]);
@@ -464,6 +465,7 @@ cd_util_create_sp (CdUtilPrivate *priv,
 	if (dot != NULL)
 		*dot = '\0';
 	cd_it8_set_title (cmf, title);
+	cd_it8_set_enable_created (cmf, FALSE);
 
 	/* save */
 	file = g_file_new_for_path (values[0]);
-- 
2.7.0

From fc72fa8fe89e1eae4cbda2f4eed806756e1fb88a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Bobbio?= <lu...@debian.org>
Date: Sat, 20 Feb 2016 12:55:57 +0100
Subject: [PATCH 2/2] cd-create-profile: Add support for SOURCE_DATE_EPOCH

When creating profiles, the current time used to be written in
the generated header as the creation date/time. This prevents
cd-create-profile from generating the same bytes, despite
getting the same input. Also, as cd-create-profile transforms
an XML description into a binary ICC profile, the current time
does not reflect will when the profile was actually created.

So we now use the modification time of the source file as the
creation date/time. However, if the SOURCE_DATE_EPOCH environment
variable is specified, its value will be used instead to ease
reproducible builds.

For more details about SOURCE_DATE_EPOCH, see
https://reproducible-builds.org/specs/source-date-epoch/

This uses cmsSetHeaderCreationDateTime() and thus requires a
version of lcms2 with this feature.
---
 client/cd-create-profile.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 57 insertions(+)

diff --git a/client/cd-create-profile.c b/client/cd-create-profile.c
index d9159a3..f0edee9 100644
--- a/client/cd-create-profile.c
+++ b/client/cd-create-profile.c
@@ -22,10 +22,14 @@
 #include "config.h"
 
 #include <glib/gi18n.h>
+#include <glib/gstdio.h>
 #include <gio/gio.h>
 #include <locale.h>
 #include <lcms2.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <stdio.h>
 #include <math.h>
 #include <colord-private.h>
 
@@ -686,6 +690,55 @@ cd_util_icc_set_metadata_coverage (CdIcc *icc, GError **error)
 }
 
 /**
+ * cd_util_adjust_creation_time:
+ **/
+static gboolean
+cd_util_adjust_creation_time (CdUtilPrivate *priv, const char *source_filename,  GError **error)
+{
+	GStatBuf st;
+	struct tm *creation_time;
+	time_t build_date = 0;
+	char *source_date_epoch_string;
+	unsigned long long source_date_epoch;
+	char *endptr;
+
+	/* adjust creation time to match the XML one or SOURCE_DATE_EPOCH if specified and older */
+	source_date_epoch_string = getenv ("SOURCE_DATE_EPOCH");
+	if (source_date_epoch_string) {
+		errno = 0;
+		source_date_epoch = strtoull (source_date_epoch_string, &endptr, 10);
+		if ((source_date_epoch == ERANGE && (source_date_epoch == ULLONG_MAX || source_date_epoch == 0))
+		|| (errno != 0 && source_date_epoch == 0)) {
+		g_set_error (error, 1, 0, "Environment variable $SOURCE_DATE_EPOCH: strtoull: %s\n", g_strerror (errno));
+			return FALSE;
+		}
+		if (endptr == source_date_epoch_string) {
+			g_set_error (error, 1, 0, "Environment variable $SOURCE_DATE_EPOCH: No digits were found: %s\n", endptr);
+			return FALSE;
+		}
+		if (*endptr != '\0') {
+			g_set_error (error, 1, 0, "Environment variable $SOURCE_DATE_EPOCH: Trailing garbage: %s\n", endptr);
+			return FALSE;
+		}
+		if (source_date_epoch > ULONG_MAX) {
+			g_set_error (error, 1, 0, "Environment variable $SOURCE_DATE_EPOCH: value must be smaller than or equal to: %lu but was found to be: %llu \n", ULONG_MAX, source_date_epoch);
+			return FALSE;
+		}
+		build_date = source_date_epoch;
+	}
+
+	if (g_stat (source_filename, &st) >= 0) {
+		if (!build_date || st.st_mtime <= build_date) {
+			build_date = st.st_mtime;
+		}
+	}
+	if ((creation_time = gmtime (&build_date)) != NULL) {
+		cmsSetHeaderCreationDateTime (priv->lcms_profile, creation_time);
+	}
+	return TRUE;
+}
+
+/**
  * cd_util_create_from_xml:
  **/
 static gboolean
@@ -764,6 +817,10 @@ cd_util_create_from_xml (CdUtilPrivate *priv,
 				     cd_dom_get_node_data (tmp));
 	}
 
+	ret = cd_util_adjust_creation_time(priv, filename, error);
+	if (!ret)
+		return FALSE;
+
 	/* add CMS defines */
 	cd_icc_add_metadata (priv->icc,
 			     CD_PROFILE_METADATA_CMF_PRODUCT,
-- 
2.7.0

Attachment: signature.asc
Description: Digital signature

Reply via email to