<commit_before>/*
 * libefiboot - library for the manipulation of EFI boot variables
 * Copyright 2012-2015 Red Hat, Inc.
 * Copyright (C) 2001 Dell Computer Corporation <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <efivar.h>
#include "dp.h"

typedef struct efi_load_option_s {
	uint32_t attributes;
	uint16_t file_path_list_length;
	uint16_t description[];
	// uint8_t file_path_list[];
	// uint8_t optional_data[];
} efi_load_option;

ssize_t
__attribute__((__nonnull__ (6)))
__attribute__((__visibility__ ("default")))
efi_make_load_option(uint8_t *buf, ssize_t size, uint32_t attributes,
		     efidp dp, ssize_t dp_size, unsigned char *description,
		     uint8_t *optional_data, size_t optional_data_size)
{
	if (!description || (!optional_data && optional_data_size != 0)) {
		errno = EINVAL;
		return -1;
	}

	if (!dp && dp_size == 0) {
		errno = EINVAL;
		return -1;
	}

	ssize_t desc_len = utf8len((uint8_t *)description, 1024) * 2 + 2;
	ssize_t sz = sizeof (attributes)
		     + sizeof (uint16_t) + desc_len
		     + dp_size + optional_data_size;
	if (size == 0)
		return sz;
	if (size < sz) {
		errno = ENOSPC;
		return -1;
	}

	uint8_t *pos = buf;

	*(uint32_t *)pos = attributes;
	pos += sizeof (attributes);

	*(uint16_t *)pos = dp_size;
	pos += sizeof (uint16_t);

	utf8_to_ucs2((uint16_t *)pos, desc_len, 1, (uint8_t *)description);
	pos += desc_len;

	memcpy(pos, dp, dp_size);
	pos += dp_size;

	if (optional_data && optional_data_size > 0)
		memcpy(pos, optional_data, optional_data_size);

	return sz;
}

ssize_t
__attribute__((__nonnull__ (1)))
__attribute__((__visibility__ ("default")))
efi_loadopt_optional_data_size(efi_load_option *opt, size_t size)
{
	size_t sz;
	uint8_t *p;

	if (!opt)
		return -1;

	if (size < sizeof(*opt))
		return -1;
	size -= sizeof(*opt);
	if (size < opt->file_path_list_length)
		return -1;
	sz = ucs2size(opt->description, size);
	if (sz == size) // since there's no room for a file path...
		return -1;
	p = (uint8_t *)(opt->description) + sz;
	size -= sz;

	if (!efidp_is_valid((const_efidp)p, size))
		return -1;
	sz = efidp_size((const_efidp)p);
	p += sz;
	size -= sz;<commit_msg>Load options are packed...<commit_after>/*
 * libefiboot - library for the manipulation of EFI boot variables
 * Copyright 2012-2015 Red Hat, Inc.
 * Copyright (C) 2001 Dell Computer Corporation <<EMAIL>>
 *
 * This library is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this library.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <efivar.h>
#include "dp.h"

typedef struct efi_load_option_s {
	uint32_t attributes;
	uint16_t file_path_list_length;
	uint16_t description[];
	// uint8_t file_path_list[];
	// uint8_t optional_data[];
}
__attribute__((packed))
efi_load_option;

ssize_t
__attribute__((__nonnull__ (6)))
__attribute__((__visibility__ ("default")))
efi_make_load_option(uint8_t *buf, ssize_t size, uint32_t attributes,
		     efidp dp, ssize_t dp_size, unsigned char *description,
		     uint8_t *optional_data, size_t optional_data_size)
{
	if (!description || (!optional_data && optional_data_size != 0)) {
		errno = EINVAL;
		return -1;
	}

	if (!dp && dp_size == 0) {
		errno = EINVAL;
		return -1;
	}

	ssize_t desc_len = utf8len((uint8_t *)description, 1024) * 2 + 2;
	ssize_t sz = sizeof (attributes)
		     + sizeof (uint16_t) + desc_len
		     + dp_size + optional_data_size;
	if (size == 0)
		return sz;
	if (size < sz) {
		errno = ENOSPC;
		return -1;
	}

	uint8_t *pos = buf;

	*(uint32_t *)pos = attributes;
	pos += sizeof (attributes);

	*(uint16_t *)pos = dp_size;
	pos += sizeof (uint16_t);

	utf8_to_ucs2((uint16_t *)pos, desc_len, 1, (uint8_t *)description);
	pos += desc_len;

	memcpy(pos, dp, dp_size);
	pos += dp_size;

	if (optional_data && optional_data_size > 0)
		memcpy(pos, optional_data, optional_data_size);

	return sz;
}

ssize_t
__attribute__((__nonnull__ (1)))
__attribute__((__visibility__ ("default")))
efi_loadopt_optional_data_size(efi_load_option *opt, size_t size)
{
	size_t sz;
	uint8_t *p;

	if (!opt)
		return -1;

	if (size < sizeof(*opt))
		return -1;
	size -= sizeof(*opt);
	if (size < opt->file_path_list_length)
		return -1;
	sz = ucs2size(opt->description, size);
	if (sz >= size) // since there's no room for a file path...
		return -1;
	p = (uint8_t *)(opt->description) + sz;
	size -= sz;

	if (!efidp_is_valid((const_efidp)p, size))
		return -1;
	sz = efidp_size((const_efidp)p);
	p += sz;
	size -= sz;
{'fraction_non_alphanumeric': 0.12192494164122823, 'fraction_numerical': 0.023343508708924404, 'mean_word_length': 4.091407678244972, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6028615', 'n_tokens_mistral': 2123, 'n_tokens_neox': 1975, 'n_words': 613}