/*
  zip_source_crc.c -- pass-through source that calculates CRC32 and size
  Copyright (C) 2009-2019 Dieter Baron and Thomas Klausner

  This file is part of libzip, a library to manipulate ZIP archives.
  The authors can be contacted at <libzip@nih.at>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
  3. The names of the authors may not be used to endorse or promote
     products derived from this software without specific prior
     written permission.

  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


#include <limits.h>
#include <stdlib.h>
#include <string.h>

#include "zipint.h"

struct crc_context {
    int validate;     /* whether to check CRC on EOF and return error on mismatch */
    int crc_complete; /* whether CRC was computed for complete file */
    zip_error_t error;
    zip_uint64_t size;
    zip_uint64_t position;     /* current reading position */
    zip_uint64_t crc_position; /* how far we've computed the CRC */
    zip_uint32_t crc;
};

static zip_int64_t crc_read(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);


zip_source_t *
zip_source_crc(zip_t *za, zip_source_t *src, int validate) {
    struct crc_context *ctx;

    if (src == NULL) {
	zip_error_set(&za->error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    if ((ctx = (struct crc_context *)malloc(sizeof(*ctx))) == NULL) {
	zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    zip_error_init(&ctx->error);
    ctx->validate = validate;
    ctx->crc_complete = 0;
    ctx->crc_position = 0;
    ctx->crc = (zip_uint32_t)crc32(0, NULL, 0);
    ctx->size = 0;

    return zip_source_layered(za, src, crc_read, ctx);
}


static zip_int64_t
crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
    struct crc_context *ctx;
    zip_int64_t n;

    ctx = (struct crc_context *)_ctx;

    switch (cmd) {
    case ZIP_SOURCE_OPEN:
	ctx->position = 0;
	return 0;

    case ZIP_SOURCE_READ:
	if ((n = zip_source_read(src, data, len)) < 0) {
	    _zip_error_set_from_source(&ctx->error, src);
	    return -1;
	}

	if (n == 0) {
	    if (ctx->crc_position == ctx->position) {
		ctx->crc_complete = 1;
		ctx->size = ctx->position;

		if (ctx->validate) {
		    struct zip_stat st;

		    if (zip_source_stat(src, &st) < 0) {
			_zip_error_set_from_source(&ctx->error, src);
			return -1;
		    }

		    if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) {
			zip_error_set(&ctx->error, ZIP_ER_CRC, 0);
			return -1;
		    }
		    if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
			zip_error_set(&ctx->error, ZIP_ER_INCONS, 0);
			return -1;
		    }
		}
	    }
	}
	else if (!ctx->crc_complete && ctx->position <= ctx->crc_position) {
	    zip_uint64_t i, nn;

	    for (i = ctx->crc_position - ctx->position; i < (zip_uint64_t)n; i += nn) {
		nn = ZIP_MIN(UINT_MAX, (zip_uint64_t)n - i);

		ctx->crc = (zip_uint32_t)crc32(ctx->crc, (const Bytef *)data + i, (uInt)nn);
		ctx->crc_position += nn;
	    }
	}
	ctx->position += (zip_uint64_t)n;
	return n;

    case ZIP_SOURCE_CLOSE:
	return 0;

    case ZIP_SOURCE_STAT: {
	zip_stat_t *st;

	st = (zip_stat_t *)data;

	if (ctx->crc_complete) {
	    /* TODO: Set comp_size, comp_method, encryption_method?
		    After all, this only works for uncompressed data. */
	    st->size = ctx->size;
	    st->crc = ctx->crc;
	    st->comp_size = ctx->size;
	    st->comp_method = ZIP_CM_STORE;
	    st->encryption_method = ZIP_EM_NONE;
	    st->valid |= ZIP_STAT_SIZE | ZIP_STAT_CRC | ZIP_STAT_COMP_SIZE | ZIP_STAT_COMP_METHOD | ZIP_STAT_ENCRYPTION_METHOD;
	}
	return 0;
    }

    case ZIP_SOURCE_ERROR:
	return zip_error_to_data(&ctx->error, data, len);

    case ZIP_SOURCE_FREE:
	free(ctx);
	return 0;

    case ZIP_SOURCE_SUPPORTS: {
	zip_int64_t mask = zip_source_supports(src);

	if (mask < 0) {
	    _zip_error_set_from_source(&ctx->error, src);
	    return -1;
	}

	return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_GET_COMPRESSION_FLAGS, -1);
    }

    case ZIP_SOURCE_SEEK: {
	zip_int64_t new_position;
	zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);

	if (args == NULL) {
	    return -1;
	}
	if (zip_source_seek(src, args->offset, args->whence) < 0 || (new_position = zip_source_tell(src)) < 0) {
	    _zip_error_set_from_source(&ctx->error, src);
	    return -1;
	}

	ctx->position = (zip_uint64_t)new_position;

	return 0;
    }

    case ZIP_SOURCE_TELL:
	return (zip_int64_t)ctx->position;

    default:
	zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
	return -1;
    }
}
