// SPDX-License-Identifier: GPL-2.0
/*
 *
 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
 *
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/stddef.h>
#include <linux/string.h>
#include <linux/types.h>

#include "debug.h"
#include "ntfs_fs.h"

// clang-format off
/* Src buffer is zero. */
#define LZNT_ERROR_ALL_ZEROS	1
#define LZNT_CHUNK_SIZE		0x1000
// clang-format on

struct lznt_hash {
	const u8 *p1;
	const u8 *p2;
};

struct lznt {
	const u8 *unc;
	const u8 *unc_end;
	const u8 *best_match;
	size_t max_len;
	bool std;

	struct lznt_hash hash[LZNT_CHUNK_SIZE];
};

static inline size_t get_match_len(const u8 *ptr, const u8 *end, const u8 *prev,
				   size_t max_len)
{
	size_t len = 0;

	while (ptr + len < end && ptr[len] == prev[len] && ++len < max_len)
		;
	return len;
}

static size_t longest_match_std(const u8 *src, struct lznt *ctx)
{
	size_t hash_index;
	size_t len1 = 0, len2 = 0;
	const u8 **hash;

	hash_index =
		((40543U * ((((src[0] << 4) ^ src[1]) << 4) ^ src[2])) >> 4) &
		(LZNT_CHUNK_SIZE - 1);

	hash = &(ctx->hash[hash_index].p1);

	if (hash[0] >= ctx->unc && hash[0] < src && hash[0][0] == src[0] &&
	    hash[0][1] == src[1] && hash[0][2] == src[2]) {
		len1 = 3;
		if (ctx->max_len > 3)
			len1 += get_match_len(src + 3, ctx->unc_end,
					      hash[0] + 3, ctx->max_len - 3);
	}

	if (hash[1] >= ctx->unc && hash[1] < src && hash[1][0] == src[0] &&
	    hash[1][1] == src[1] && hash[1][2] == src[2]) {
		len2 = 3;
		if (ctx->max_len > 3)
			len2 += get_match_len(src + 3, ctx->unc_end,
					      hash[1] + 3, ctx->max_len - 3);
	}

	/* Compare two matches and select the best one. */
	if (len1 < len2) {
		ctx->best_match = hash[1];
		len1 = len2;
	} else {
		ctx->best_match = hash[0];
	}

	hash[1] = hash[0];
	hash[0] = src;
	return len1;
}

static size_t longest_match_best(const u8 *src, struct lznt *ctx)
{
	size_t max_len;
	const u8 *ptr;

	if (ctx->unc >= src || !ctx->max_len)
		return 0;

	max_len = 0;
	for (ptr = ctx->unc; ptr < src; ++ptr) {
		size_t len =
			get_match_len(src, ctx->unc_end, ptr, ctx->max_len);
		if (len >= max_len) {
			max_len = len;
			ctx->best_match = ptr;
		}
	}

	return max_len >= 3 ? max_len : 0;
}

static const size_t s_max_len[] = {
	0x1002, 0x802, 0x402, 0x202, 0x102, 0x82, 0x42, 0x22, 0x12,
};

static const size_t s_max_off[] = {
	0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
};

static inline u16 make_pair(size_t offset, size_t len, size_t index)
{
	return ((offset - 1) << (12 - index)) |
	       ((len - 3) & (((1 << (12 - index)) - 1)));
}

static inline size_t parse_pair(u16 pair, size_t *offset, size_t index)
{
	*offset = 1 + (pair >> (12 - index));
	return 3 + (pair & ((1 << (12 - index)) - 1));
}

/*
 * compress_chunk
 *
 * Return:
 * * 0	- Ok, @cmpr contains @cmpr_chunk_size bytes of compressed data.
 * * 1	- Input buffer is full zero.
 * * -2 - The compressed buffer is too small to hold the compressed data.
 */
static inline int compress_chunk(size_t (*match)(const u8 *, struct lznt *),
				 const u8 *unc, const u8 *unc_end, u8 *cmpr,
				 u8 *cmpr_end, size_t *cmpr_chunk_size,
				 struct lznt *ctx)
{
	size_t cnt = 0;
	size_t idx = 0;
	const u8 *up = unc;
	u8 *cp = cmpr + 3;
	u8 *cp2 = cmpr + 2;
	u8 not_zero = 0;
	/* Control byte of 8-bit values: ( 0 - means byte as is, 1 - short pair ). */
	u8 ohdr = 0;
	u8 *last;
	u16 t16;

	if (unc + LZNT_CHUNK_SIZE < unc_end)
		unc_end = unc + LZNT_CHUNK_SIZE;

	last = min(cmpr + LZNT_CHUNK_SIZE + sizeof(short), cmpr_end);

	ctx->unc = unc;
	ctx->unc_end = unc_end;
	ctx->max_len = s_max_len[0];

	while (up < unc_end) {
		size_t max_len;

		while (unc + s_max_off[idx] < up)
			ctx->max_len = s_max_len[++idx];

		/* Find match. */
		max_len = up + 3 <= unc_end ? (*match)(up, ctx) : 0;

		if (!max_len) {
			if (cp >= last)
				goto NotCompressed;
			not_zero |= *cp++ = *up++;
		} else if (cp + 1 >= last) {
			goto NotCompressed;
		} else {
			t16 = make_pair(up - ctx->best_match, max_len, idx);
			*cp++ = t16;
			*cp++ = t16 >> 8;

			ohdr |= 1 << cnt;
			up += max_len;
		}

		cnt = (cnt + 1) & 7;
		if (!cnt) {
			*cp2 = ohdr;
			ohdr = 0;
			cp2 = cp;
			cp += 1;
		}
	}

	if (cp2 < last)
		*cp2 = ohdr;
	else
		cp -= 1;

	*cmpr_chunk_size = cp - cmpr;

	t16 = (*cmpr_chunk_size - 3) | 0xB000;
	cmpr[0] = t16;
	cmpr[1] = t16 >> 8;

	return not_zero ? 0 : LZNT_ERROR_ALL_ZEROS;

NotCompressed:

	if ((cmpr + LZNT_CHUNK_SIZE + sizeof(short)) > last)
		return -2;

	/*
	 * Copy non cmpr data.
	 * 0x3FFF == ((LZNT_CHUNK_SIZE + 2 - 3) | 0x3000)
	 */
	cmpr[0] = 0xff;
	cmpr[1] = 0x3f;

	memcpy(cmpr + sizeof(short), unc, LZNT_CHUNK_SIZE);
	*cmpr_chunk_size = LZNT_CHUNK_SIZE + sizeof(short);

	return 0;
}

static inline ssize_t decompress_chunk(u8 *unc, u8 *unc_end, const u8 *cmpr,
				       const u8 *cmpr_end)
{
	u8 *up = unc;
	u8 ch = *cmpr++;
	size_t bit = 0;
	size_t index = 0;
	u16 pair;
	size_t offset, length;

	/* Do decompression until pointers are inside range. */
	while (up < unc_end && cmpr < cmpr_end) {
		/* Correct index */
		while (unc + s_max_off[index] < up)
			index += 1;

		/* Check the current flag for zero. */
		if (!(ch & (1 << bit))) {
			/* Just copy byte. */
			*up++ = *cmpr++;
			goto next;
		}

		/* Check for boundary. */
		if (cmpr + 1 >= cmpr_end)
			return -EINVAL;

		/* Read a short from little endian stream. */
		pair = cmpr[1];
		pair <<= 8;
		pair |= cmpr[0];

		cmpr += 2;

		/* Translate packed information into offset and length. */
		length = parse_pair(pair, &offset, index);

		/* Check offset for boundary. */
		if (unc + offset > up)
			return -EINVAL;

		/* Truncate the length if necessary. */
		if (up + length >= unc_end)
			length = unc_end - up;

		/* Now we copy bytes. This is the heart of LZ algorithm. */
		for (; length > 0; length--, up++)
			*up = *(up - offset);

next:
		/* Advance flag bit value. */
		bit = (bit + 1) & 7;

		if (!bit) {
			if (cmpr >= cmpr_end)
				break;

			ch = *cmpr++;
		}
	}

	/* Return the size of uncompressed data. */
	return up - unc;
}

/*
 * get_lznt_ctx
 * @level: 0 - Standard compression.
 *	   !0 - Best compression, requires a lot of cpu.
 */
struct lznt *get_lznt_ctx(int level)
{
	struct lznt *r = kzalloc(level ? offsetof(struct lznt, hash) :
					 sizeof(struct lznt),
				 GFP_NOFS);

	if (r)
		r->std = !level;
	return r;
}

/*
 * compress_lznt - Compresses @unc into @cmpr
 *
 * Return:
 * * +x - Ok, @cmpr contains 'final_compressed_size' bytes of compressed data.
 * * 0 - Input buffer is full zero.
 */
size_t compress_lznt(const void *unc, size_t unc_size, void *cmpr,
		     size_t cmpr_size, struct lznt *ctx)
{
	int err;
	size_t (*match)(const u8 *src, struct lznt *ctx);
	u8 *p = cmpr;
	u8 *end = p + cmpr_size;
	const u8 *unc_chunk = unc;
	const u8 *unc_end = unc_chunk + unc_size;
	bool is_zero = true;

	if (ctx->std) {
		match = &longest_match_std;
		memset(ctx->hash, 0, sizeof(ctx->hash));
	} else {
		match = &longest_match_best;
	}

	/* Compression cycle. */
	for (; unc_chunk < unc_end; unc_chunk += LZNT_CHUNK_SIZE) {
		cmpr_size = 0;
		err = compress_chunk(match, unc_chunk, unc_end, p, end,
				     &cmpr_size, ctx);
		if (err < 0)
			return unc_size;

		if (is_zero && err != LZNT_ERROR_ALL_ZEROS)
			is_zero = false;

		p += cmpr_size;
	}

	if (p <= end - 2)
		p[0] = p[1] = 0;

	return is_zero ? 0 : PtrOffset(cmpr, p);
}

/*
 * decompress_lznt - Decompress @cmpr into @unc.
 */
ssize_t decompress_lznt(const void *cmpr, size_t cmpr_size, void *unc,
			size_t unc_size)
{
	const u8 *cmpr_chunk = cmpr;
	const u8 *cmpr_end = cmpr_chunk + cmpr_size;
	u8 *unc_chunk = unc;
	u8 *unc_end = unc_chunk + unc_size;
	u16 chunk_hdr;

	if (cmpr_size < sizeof(short))
		return -EINVAL;

	/* Read chunk header. */
	chunk_hdr = cmpr_chunk[1];
	chunk_hdr <<= 8;
	chunk_hdr |= cmpr_chunk[0];

	/* Loop through decompressing chunks. */
	for (;;) {
		size_t chunk_size_saved;
		size_t unc_use;
		size_t cmpr_use = 3 + (chunk_hdr & (LZNT_CHUNK_SIZE - 1));

		/* Check that the chunk actually fits the supplied buffer. */
		if (cmpr_chunk + cmpr_use > cmpr_end)
			return -EINVAL;

		/* First make sure the chunk contains compressed data. */
		if (chunk_hdr & 0x8000) {
			/* Decompress a chunk and return if we get an error. */
			ssize_t err =
				decompress_chunk(unc_chunk, unc_end,
						 cmpr_chunk + sizeof(chunk_hdr),
						 cmpr_chunk + cmpr_use);
			if (err < 0)
				return err;
			unc_use = err;
		} else {
			/* This chunk does not contain compressed data. */
			unc_use = unc_chunk + LZNT_CHUNK_SIZE > unc_end ?
					  unc_end - unc_chunk :
					  LZNT_CHUNK_SIZE;

			if (cmpr_chunk + sizeof(chunk_hdr) + unc_use >
			    cmpr_end) {
				return -EINVAL;
			}

			memcpy(unc_chunk, cmpr_chunk + sizeof(chunk_hdr),
			       unc_use);
		}

		/* Advance pointers. */
		cmpr_chunk += cmpr_use;
		unc_chunk += unc_use;

		/* Check for the end of unc buffer. */
		if (unc_chunk >= unc_end)
			break;

		/* Proceed the next chunk. */
		if (cmpr_chunk > cmpr_end - 2)
			break;

		chunk_size_saved = LZNT_CHUNK_SIZE;

		/* Read chunk header. */
		chunk_hdr = cmpr_chunk[1];
		chunk_hdr <<= 8;
		chunk_hdr |= cmpr_chunk[0];

		if (!chunk_hdr)
			break;

		/* Check the size of unc buffer. */
		if (unc_use < chunk_size_saved) {
			size_t t1 = chunk_size_saved - unc_use;
			u8 *t2 = unc_chunk + t1;

			/* 'Zero' memory. */
			if (t2 >= unc_end)
				break;

			memset(unc_chunk, 0, t1);
			unc_chunk = t2;
		}
	}

	/* Check compression boundary. */
	if (cmpr_chunk > cmpr_end)
		return -EINVAL;

	/*
	 * The unc size is just a difference between current
	 * pointer and original one.
	 */
	return PtrOffset(unc, unc_chunk);
}
