#include <assert.h>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include "regex.h"
#include "label_file.h"
#include "selinux_internal.h"

#ifdef USE_PCRE2
#define REGEX_ARCH_SIZE_T PCRE2_SIZE
#else
#define REGEX_ARCH_SIZE_T size_t
#endif

#ifndef __BYTE_ORDER__

/* If the compiler doesn't define __BYTE_ORDER__, try to use the C
 * library <endian.h> header definitions. */
#include <endian.h>
#ifndef __BYTE_ORDER
#error Neither __BYTE_ORDER__ nor __BYTE_ORDER defined. Unable to determine endianness.
#endif

#define __ORDER_LITTLE_ENDIAN __LITTLE_ENDIAN
#define __ORDER_BIG_ENDIAN __BIG_ENDIAN
#define __BYTE_ORDER__ __BYTE_ORDER

#endif

#ifdef USE_PCRE2
static pthread_key_t match_data_key;
static int match_data_key_initialized = -1;
static pthread_mutex_t key_mutex = PTHREAD_MUTEX_INITIALIZER;
static __thread char match_data_initialized;

char const *regex_arch_string(void)
{
	static char arch_string_buffer[32];
	static char const *arch_string = "";
	char const *endianness = NULL;
	int rc;

	if (arch_string[0] == '\0') {
		if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
			endianness = "el";
		else if (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
			endianness = "eb";

		if (!endianness)
			return NULL;

		rc = snprintf(arch_string_buffer, sizeof(arch_string_buffer),
				"%zu-%zu-%s", sizeof(void *),
				sizeof(REGEX_ARCH_SIZE_T),
				endianness);
		if (rc < 0)
			abort();

		arch_string = &arch_string_buffer[0];
	}
	return arch_string;
}

struct regex_data {
	pcre2_code *regex; /* compiled regular expression */
};

int regex_prepare_data(struct regex_data **regex, char const *pattern_string,
		       struct regex_error_data *errordata)
{
	memset(errordata, 0, sizeof(struct regex_error_data));

	*regex = regex_data_create();
	if (!(*regex))
		return -1;

	(*regex)->regex = pcre2_compile(
	    (PCRE2_SPTR)pattern_string, PCRE2_ZERO_TERMINATED, PCRE2_DOTALL,
	    &errordata->error_code, &errordata->error_offset, NULL);
	if (!(*regex)->regex) {
		goto err;
	}

	return 0;

err:
	regex_data_free(*regex);
	*regex = NULL;
	return -1;
}

char const *regex_version(void)
{
	static char version_buf[256];
	size_t len = pcre2_config(PCRE2_CONFIG_VERSION, NULL);
	if (len <= 0 || len > sizeof(version_buf))
		return NULL;

	pcre2_config(PCRE2_CONFIG_VERSION, version_buf);
	return version_buf;
}

int regex_load_mmap(struct mmap_area *mmap_area, struct regex_data **regex,
		    int do_load_precompregex, bool *regex_compiled)
{
	int rc;
	uint32_t entry_len;

	*regex_compiled = false;
	rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t));
	if (rc < 0)
		return -1;

	if (entry_len && do_load_precompregex) {
		/*
		 * this should yield exactly one because we store one pattern at
		 * a time
		 */
		rc = pcre2_serialize_get_number_of_codes(mmap_area->next_addr);
		if (rc != 1)
			return -1;

		*regex = regex_data_create();
		if (!*regex)
			return -1;

		rc = pcre2_serialize_decode(&(*regex)->regex, 1,
					    (PCRE2_SPTR)mmap_area->next_addr,
					    NULL);
		if (rc != 1)
			goto err;

		*regex_compiled = true;
	}

	/* and skip the decoded bit */
	rc = next_entry(NULL, mmap_area, entry_len);
	if (rc < 0)
		goto err;

	return 0;
err:
	regex_data_free(*regex);
	*regex = NULL;
	return -1;
}

int regex_writef(struct regex_data *regex, FILE *fp, int do_write_precompregex)
{
	int rc = 0;
	size_t len;
	PCRE2_SIZE serialized_size;
	uint32_t to_write = 0;
	PCRE2_UCHAR *bytes = NULL;

	if (do_write_precompregex) {
		/* encode the pattern for serialization */
		rc = pcre2_serialize_encode((const pcre2_code **)&regex->regex,
					    1, &bytes, &serialized_size, NULL);
		if (rc != 1) {
			rc = -1;
			goto out;
		}
		to_write = serialized_size;
	}

	/* write serialized pattern's size */
	len = fwrite(&to_write, sizeof(uint32_t), 1, fp);
	if (len != 1) {
		rc = -1;
		goto out;
	}

	if (do_write_precompregex) {
		/* write serialized pattern */
		len = fwrite(bytes, 1, to_write, fp);
		if (len != to_write)
			rc = -1;
	}

out:
	if (bytes)
		pcre2_serialize_free(bytes);

	return rc;
}

static void __attribute__((destructor)) match_data_thread_free(void *key)
{
	void *value;
	pcre2_match_data *match_data;

	if (match_data_key_initialized <= 0 || !match_data_initialized)
		return;

	value = __selinux_getspecific(match_data_key);
	match_data = value ? value : key;

	pcre2_match_data_free(match_data);

	__pthread_mutex_lock(&key_mutex);
	if (--match_data_key_initialized == 1) {
		__selinux_key_delete(match_data_key);
		match_data_key_initialized = -1;
	}
	__pthread_mutex_unlock(&key_mutex);
}

void regex_data_free(struct regex_data *regex)
{
	if (regex) {
		if (regex->regex)
			pcre2_code_free(regex->regex);
		free(regex);
	}
}

int regex_match(struct regex_data *regex, char const *subject, int partial)
{
	int rc;
	bool slow;
	pcre2_match_data *match_data = NULL;

	if (match_data_key_initialized > 0) {
		if (match_data_initialized == 0) {
			match_data = pcre2_match_data_create(1, NULL);
			if (match_data) {
				match_data_initialized = 1;
				__selinux_setspecific(match_data_key,
							match_data);
				__pthread_mutex_lock(&key_mutex);
				match_data_key_initialized++;
				__pthread_mutex_unlock(&key_mutex);
			}
		} else
			match_data = __selinux_getspecific(match_data_key);
	}

	slow = (match_data_key_initialized <= 0 || match_data == NULL);
	if (slow) {
		match_data = pcre2_match_data_create_from_pattern(regex->regex,
									NULL);
		if (!match_data)
			return REGEX_ERROR;
	}

	rc = pcre2_match(
	    regex->regex, (PCRE2_SPTR)subject, PCRE2_ZERO_TERMINATED, 0,
	    partial ? PCRE2_PARTIAL_SOFT : 0, match_data, NULL);

	if (slow)
		pcre2_match_data_free(match_data);

	if (rc >= 0)
		return REGEX_MATCH;
	switch (rc) {
	case PCRE2_ERROR_PARTIAL:
		return REGEX_MATCH_PARTIAL;
	case PCRE2_ERROR_NOMATCH:
		return REGEX_NO_MATCH;
	default:
		return REGEX_ERROR;
	}
}

/*
 * TODO Replace this compare function with something that actually compares the
 * regular expressions.
 * This compare function basically just compares the binary representations of
 * the automatons, and because this representation contains pointers and
 * metadata, it can only return a match if regex1 == regex2.
 * Preferably, this function would be replaced with an algorithm that computes
 * the equivalence of the automatons systematically.
 */
int regex_cmp(struct regex_data *regex1, struct regex_data *regex2)
{
	int rc;
	size_t len1, len2;
	rc = pcre2_pattern_info(regex1->regex, PCRE2_INFO_SIZE, &len1);
	assert(rc == 0);
	rc = pcre2_pattern_info(regex2->regex, PCRE2_INFO_SIZE, &len2);
	assert(rc == 0);
	if (len1 != len2 || memcmp(regex1->regex, regex2->regex, len1))
		return SELABEL_INCOMPARABLE;

	return SELABEL_EQUAL;
}

struct regex_data *regex_data_create(void)
{
	struct regex_data *regex_data =
		(struct regex_data *)calloc(1, sizeof(struct regex_data));
	if (!regex_data)
		return NULL;

	__pthread_mutex_lock(&key_mutex);
	if (match_data_key_initialized < 0) {
		match_data_key_initialized = !__selinux_key_create(
							&match_data_key,
							match_data_thread_free);
	}
	__pthread_mutex_unlock(&key_mutex);

	return regex_data;
}

#else // !USE_PCRE2
char const *regex_arch_string(void)
{
	return "N/A";
}

/* Prior to version 8.20, libpcre did not have pcre_free_study() */
#if (PCRE_MAJOR < 8 || (PCRE_MAJOR == 8 && PCRE_MINOR < 20))
#define pcre_free_study pcre_free
#endif

struct regex_data {
	int owned;   /*
		      * non zero if regex and pcre_extra is owned by this
		      * structure and thus must be freed on destruction.
		      */
	pcre *regex; /* compiled regular expression */
	union {
		pcre_extra *sd; /* pointer to extra compiled stuff */
		pcre_extra lsd; /* used to hold the mmap'd version */
	};
};

int regex_prepare_data(struct regex_data **regex, char const *pattern_string,
		       struct regex_error_data *errordata)
{
	memset(errordata, 0, sizeof(struct regex_error_data));

	*regex = regex_data_create();
	if (!(*regex))
		return -1;

	(*regex)->regex =
	    pcre_compile(pattern_string, PCRE_DOTALL, &errordata->error_buffer,
			 &errordata->error_offset, NULL);
	if (!(*regex)->regex)
		goto err;

	(*regex)->owned = 1;

	(*regex)->sd = pcre_study((*regex)->regex, 0, &errordata->error_buffer);
	if (!(*regex)->sd && errordata->error_buffer)
		goto err;

	return 0;

err:
	regex_data_free(*regex);
	*regex = NULL;
	return -1;
}

char const *regex_version(void)
{
	return pcre_version();
}

int regex_load_mmap(struct mmap_area *mmap_area, struct regex_data **regex,
		    int do_load_precompregex __attribute__((unused)), bool *regex_compiled)
{
	int rc;
	uint32_t entry_len;
	size_t info_len;

	rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t));
	if (rc < 0 || !entry_len)
		return -1;

	*regex = regex_data_create();
	if (!(*regex))
		return -1;

	(*regex)->owned = 0;
	(*regex)->regex = (pcre *)mmap_area->next_addr;
	rc = next_entry(NULL, mmap_area, entry_len);
	if (rc < 0)
		goto err;

	/*
	 * Check that regex lengths match. pcre_fullinfo()
	 * also validates its magic number.
	 */
	rc = pcre_fullinfo((*regex)->regex, NULL, PCRE_INFO_SIZE, &info_len);
	if (rc < 0 || info_len != entry_len)
		goto err;

	rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t));
	if (rc < 0)
		goto err;

	if (entry_len) {
		(*regex)->lsd.study_data = (void *)mmap_area->next_addr;
		(*regex)->lsd.flags |= PCRE_EXTRA_STUDY_DATA;
		rc = next_entry(NULL, mmap_area, entry_len);
		if (rc < 0)
			goto err;

		/* Check that study data lengths match. */
		rc = pcre_fullinfo((*regex)->regex, &(*regex)->lsd,
				   PCRE_INFO_STUDYSIZE, &info_len);
		if (rc < 0 || info_len != entry_len)
			goto err;
	}

	*regex_compiled = true;
	return 0;

err:
	regex_data_free(*regex);
	*regex = NULL;
	return -1;
}

static inline pcre_extra *get_pcre_extra(struct regex_data *regex)
{
	if (!regex) return NULL;
	if (regex->owned) {
		return regex->sd;
	} else if (regex->lsd.study_data) {
		return &regex->lsd;
	} else {
		return NULL;
	}
}

int regex_writef(struct regex_data *regex, FILE *fp,
		 int do_write_precompregex __attribute__((unused)))
{
	int rc;
	size_t len;
	uint32_t to_write;
	size_t size;
	pcre_extra *sd = get_pcre_extra(regex);

	/* determine the size of the pcre data in bytes */
	rc = pcre_fullinfo(regex->regex, NULL, PCRE_INFO_SIZE, &size);
	if (rc < 0)
		return -1;

	/* write the number of bytes in the pcre data */
	to_write = size;
	len = fwrite(&to_write, sizeof(uint32_t), 1, fp);
	if (len != 1)
		return -1;

	/* write the actual pcre data as a char array */
	len = fwrite(regex->regex, 1, to_write, fp);
	if (len != to_write)
		return -1;

	if (sd) {
		/* determine the size of the pcre study info */
		rc =
		    pcre_fullinfo(regex->regex, sd, PCRE_INFO_STUDYSIZE, &size);
		if (rc < 0)
			return -1;
	} else
		size = 0;

	/* write the number of bytes in the pcre study data */
	to_write = size;
	len = fwrite(&to_write, sizeof(uint32_t), 1, fp);
	if (len != 1)
		return -1;

	if (sd) {
		/* write the actual pcre study data as a char array */
		len = fwrite(sd->study_data, 1, to_write, fp);
		if (len != to_write)
			return -1;
	}

	return 0;
}

void regex_data_free(struct regex_data *regex)
{
	if (regex) {
		if (regex->owned) {
			if (regex->regex)
				pcre_free(regex->regex);
			if (regex->sd)
				pcre_free_study(regex->sd);
		}
		free(regex);
	}
}

int regex_match(struct regex_data *regex, char const *subject, int partial)
{
	int rc;

	rc = pcre_exec(regex->regex, get_pcre_extra(regex),
		       subject, strlen(subject), 0,
		       partial ? PCRE_PARTIAL_SOFT : 0, NULL, 0);
	switch (rc) {
	case 0:
		return REGEX_MATCH;
	case PCRE_ERROR_PARTIAL:
		return REGEX_MATCH_PARTIAL;
	case PCRE_ERROR_NOMATCH:
		return REGEX_NO_MATCH;
	default:
		return REGEX_ERROR;
	}
}

/*
 * TODO Replace this compare function with something that actually compares the
 * regular expressions.
 * This compare function basically just compares the binary representations of
 * the automatons, and because this representation contains pointers and
 * metadata, it can only return a match if regex1 == regex2.
 * Preferably, this function would be replaced with an algorithm that computes
 * the equivalence of the automatons systematically.
 */
int regex_cmp(struct regex_data *regex1, struct regex_data *regex2)
{
	int rc;
	size_t len1, len2;
	rc = pcre_fullinfo(regex1->regex, NULL, PCRE_INFO_SIZE, &len1);
	assert(rc == 0);
	rc = pcre_fullinfo(regex2->regex, NULL, PCRE_INFO_SIZE, &len2);
	assert(rc == 0);
	if (len1 != len2 || memcmp(regex1->regex, regex2->regex, len1))
		return SELABEL_INCOMPARABLE;

	return SELABEL_EQUAL;
}

struct regex_data *regex_data_create(void)
{
	return (struct regex_data *)calloc(1, sizeof(struct regex_data));
}

#endif

void regex_format_error(struct regex_error_data const *error_data, char *buffer,
			size_t buf_size)
{
	unsigned the_end_length = buf_size > 4 ? 4 : buf_size;
	char *ptr = &buffer[buf_size - the_end_length];
	int rc = 0;
	size_t pos = 0;
	if (!buffer || !buf_size)
		return;
	rc = snprintf(buffer, buf_size, "REGEX back-end error: ");
	if (rc < 0)
		/*
		 * If snprintf fails it constitutes a logical error that needs
		 * fixing.
		 */
		abort();

	pos += rc;
	if (pos >= buf_size)
		goto truncated;

	/* Return early if there is no error to format */
#ifdef USE_PCRE2
	if (!error_data->error_code) {
		rc = snprintf(buffer + pos, buf_size - pos, "no error code");
		if (rc < 0)
			abort();
		pos += rc;
		if (pos >= buf_size)
			goto truncated;
		return;
	}
#else
	if (!error_data->error_buffer) {
		rc = snprintf(buffer + pos, buf_size - pos, "empty error");
		if (rc < 0)
			abort();
		pos += rc;
		if (pos >= buf_size)
			goto truncated;
		return;
	}
#endif

	if (error_data->error_offset > 0) {
#ifdef USE_PCRE2
		rc = snprintf(buffer + pos, buf_size - pos, "At offset %zu: ",
			      error_data->error_offset);
#else
		rc = snprintf(buffer + pos, buf_size - pos, "At offset %d: ",
			      error_data->error_offset);
#endif
		if (rc < 0)
			abort();
		pos += rc;
		if (pos >= buf_size)
			goto truncated;
	}

#ifdef USE_PCRE2
	rc = pcre2_get_error_message(error_data->error_code,
				     (PCRE2_UCHAR *)(buffer + pos),
				     buf_size - pos);
	if (rc == PCRE2_ERROR_NOMEMORY)
		goto truncated;
#else
	rc = snprintf(buffer + pos, buf_size - pos, "%s",
		      error_data->error_buffer);
	if (rc < 0)
		abort();

	if ((size_t)rc < strlen(error_data->error_buffer))
		goto truncated;
#endif

	return;

truncated:
	/* replace end of string with "..." to indicate that it was truncated */
	switch (the_end_length) {
	/* no break statements, fall-through is intended */
	case 4:
		*ptr++ = '.';
		/* FALLTHRU */
	case 3:
		*ptr++ = '.';
		/* FALLTHRU */
	case 2:
		*ptr++ = '.';
		/* FALLTHRU */
	case 1:
		*ptr++ = '\0';
		/* FALLTHRU */
	default:
		break;
	}
	return;
}
