From a68eb730558fb90bc8d9524564d8f9e58f3ccac1 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer 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 --- 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