From a68eb730558fb90bc8d9524564d8f9e58f3ccac1 Mon Sep 17 00:00:00 2001
From: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Date: Mon, 7 Oct 2019 11:20:55 +0200
Subject: Improve ABI backward & forward compatibillity

 - Padd the compressor config union
    - 128 bytes aught to be enough for everyone, i.e. future compressors.
    - Insist that the padding space is initialized to 0. If a field gets
      added to an existing compressor, it can test for 0 as a sentinel
      value.
 - Add a size field to the hook structure, aka "the Microsoft way".
    - The explanation is in the comment.
    - Don't make the Microsoft mistake of checking for >=, insist on *exact*
      size match. Future users will need a fallback if their hooks are
      rejected. But at least they will be rejected instead of silently not
      being used.
 - Add an unsupported flag check to the dir tree reader.
 - Add a basic abi unit test that, for now, checks the size of the compressor
   config struct fields.

Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
---
 lib/sqfs/comp/compressor.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

(limited to 'lib/sqfs/comp')

diff --git a/lib/sqfs/comp/compressor.c b/lib/sqfs/comp/compressor.c
index bfc20b7..902ce92 100644
--- a/lib/sqfs/comp/compressor.c
+++ b/lib/sqfs/comp/compressor.c
@@ -87,12 +87,42 @@ bool sqfs_compressor_exists(E_SQFS_COMPRESSOR id)
 
 sqfs_compressor_t *sqfs_compressor_create(const sqfs_compressor_config_t *cfg)
 {
+	sqfs_u8 padd0[sizeof(cfg->opt)];
+	int ret;
+
 	if (cfg == NULL || cfg->id < SQFS_COMP_MIN || cfg->id > SQFS_COMP_MAX)
 		return NULL;
 
 	if (compressors[cfg->id] == NULL)
 		return NULL;
 
+	memset(padd0, 0, sizeof(padd0));
+
+	switch (cfg->id) {
+	case SQFS_COMP_XZ:
+		ret = memcmp(cfg->opt.xz.padd0, padd0,
+			     sizeof(cfg->opt.xz.padd0));
+		break;
+	case SQFS_COMP_LZO:
+		ret = memcmp(cfg->opt.lzo.padd0, padd0,
+			     sizeof(cfg->opt.lzo.padd0));
+		break;
+	case SQFS_COMP_ZSTD:
+		ret = memcmp(cfg->opt.zstd.padd0, padd0,
+			     sizeof(cfg->opt.zstd.padd0));
+		break;
+	case SQFS_COMP_GZIP:
+		ret = memcmp(cfg->opt.gzip.padd0, padd0,
+			     sizeof(cfg->opt.gzip.padd0));
+		break;
+	default:
+		ret = memcmp(cfg->opt.padd0, padd0, sizeof(cfg->opt.padd0));
+		break;
+	}
+
+	if (ret != 0)
+		return NULL;
+
 	return compressors[cfg->id](cfg);
 }
 
-- 
cgit v1.2.3