Пример #1
0
/*
 * When provided with a Tpm2Command that represents a call to the
 * GetCapability command this function will extract the 'property' field.
 * On error 0 is returned.
 */
UINT32
tpm2_command_get_prop (Tpm2Command *command)
{
    if (command == NULL) {
        g_warning ("tpm2_command_get_prop passed NULL parameter");
        return 0;
    }
    if (tpm2_command_get_code (command) != TPM_CC_GetCapability) {
        g_warning ("tpm2_command_get_cap provided a Tpm2Command buffer "
                   "containing the wrong command code.");
        return 0;
    }
    return (UINT32)be32toh (PROPERTY_GET (tpm2_command_get_buffer (command)));
}
Пример #2
0
uint8_t utf8isnormalized(const char* input, size_t inputSize, size_t flags, size_t* offset)
{
	const char* src = input;
	size_t src_size = inputSize;
	uint8_t last_canonical_class = CCC_NOT_REORDERED;
	size_t found_offset = 0;
	uint8_t result = UTF8_NORMALIZATION_RESULT_YES;
	unicode_t decoded;
	uint8_t canonical_class;
	uint8_t quick_check;
	const size_t* property_index;
	const uint8_t* property_data;

	/* Validate input and flags */

	if (input == NULL ||
		inputSize == 0 ||
		(flags & (UTF8_NORMALIZE_DECOMPOSE | UTF8_NORMALIZE_COMPOSE)) == 0)
	{
		goto end;
	}

	/* Get properties */

	if ((flags & UTF8_NORMALIZE_COMPOSE) != 0)
	{
		if ((flags & UTF8_NORMALIZE_COMPATIBILITY) != 0)
		{
			property_index = QuickCheckNFKCIndexPtr;
			property_data = QuickCheckNFKCDataPtr;
		}
		else
		{
			property_index = QuickCheckNFCIndexPtr;
			property_data = QuickCheckNFCDataPtr;
		}
	}
	else
	{
		if ((flags & UTF8_NORMALIZE_COMPATIBILITY) != 0)
		{
			property_index = QuickCheckNFKDIndexPtr;
			property_data = QuickCheckNFKDDataPtr;
		}
		else
		{
			property_index = QuickCheckNFDIndexPtr;
			property_data = QuickCheckNFDDataPtr;
		}
	}

	/* Process input */

	while (src_size > 0)
	{
		/* Read codepoint at cursor */

		uint8_t read = codepoint_read(src, src_size, &decoded);
		if (read == 0)
		{
			break;
		}

		/* Get canonical combining class and quick check value */

		canonical_class = PROPERTY_GET_CCC(decoded);
		quick_check = PROPERTY_GET(property_index, property_data, decoded);

		/* Compare CCC to previous CCC */

		if (last_canonical_class > canonical_class &&
			canonical_class > CCC_NOT_REORDERED)
		{
			result = UTF8_NORMALIZATION_RESULT_NO;

			break;
		}

		/* Compare quick check value */

		if (quick_check == QuickCheckResult_No)
		{
			result = UTF8_NORMALIZATION_RESULT_NO;

			break;
		}
		else if (
			quick_check == QuickCheckResult_Maybe)
		{
			result = UTF8_NORMALIZATION_RESULT_MAYBE;
		}

		/* Append to offset */

		if (result != UTF8_NORMALIZATION_RESULT_MAYBE)
		{
			found_offset += read;
		}

		last_canonical_class = canonical_class;

		src += read;
		src_size -= read;
	}

end:
	if (offset != 0)
	{
		*offset = found_offset;
	}
	return result;
}
Пример #3
0
size_t utf8normalize(const char* input, size_t inputSize, char* target, size_t targetSize, size_t flags, int32_t* errors)
{
	char* dst = target;
	size_t dst_size = targetSize;
	StreamState stream[4];
	DecomposeState decompose_state;
	ComposeState compose_state;
	uint8_t compatibility = (flags & UTF8_NORMALIZE_COMPATIBILITY) != 0;
	StreamState* stream_output;
	uint8_t finished = 0;
	size_t bytes_written = 0;

	/*
		Decomposition uses the following process:

		input         -->  stream[0]  -->
		(decompose)   -->  stream[1]  -->
		(accumulate)  -->  stream[2]  -->
		output

		The accumulation step is necessary in order to prevent buffer overflow
		attacks.

		Composition adds another stream buffer:

		input         --> stream[0]  -->
		(decompose)   --> stream[1]  -->
		(accumulate)  --> stream[2]  -->
		(compose)     --> stream[3]  -->
		output

		Although four streaming buffers may seem excessive, they are necessary
		for preventing allocations on the heap.
	*/

	/* Check for valid flags */

	if ((flags & (UTF8_NORMALIZE_DECOMPOSE | UTF8_NORMALIZE_COMPOSE)) == 0)
	{
		UTF8_SET_ERROR(INVALID_FLAG);

		return bytes_written;
	}

	/* Validate parameters */

	UTF8_VALIDATE_PARAMETERS_CHAR(char, bytes_written);

	/* Initialize decomposition */

	memset(stream, 0, sizeof(stream));

	if (!stream_initialize(&stream[0], input, inputSize) ||
		!decompose_initialize(&decompose_state, &stream[0], &stream[1], compatibility))
	{
		UTF8_SET_ERROR(INVALID_DATA);

		return bytes_written;
	}

	stream_output = &stream[2];

	if ((flags & UTF8_NORMALIZE_COMPOSE) != 0)
	{
		/* Initialize composition */

		if (!compose_initialize(&compose_state, &stream[2], &stream[3], compatibility))
		{
			UTF8_SET_ERROR(INVALID_DATA);

			return bytes_written;
		}

		stream_output = &stream[3];
	}

	do
	{
		uint8_t write = 0;

		/* Accumulate decomposed input in next stream */

		if (stream[1].current > 0)
		{
			unicode_t* src_codepoint = stream[1].codepoint;
			unicode_t* dst_codepoint = stream[2].codepoint + stream[2].filled;
			uint8_t* src_qc = stream[1].quick_check;
			uint8_t* dst_qc = stream[2].quick_check + stream[2].filled;
			uint8_t* src_ccc = stream[1].canonical_combining_class;
			uint8_t* dst_ccc = stream[2].canonical_combining_class + stream[2].filled;

			if ((flags & UTF8_NORMALIZE_COMPOSE) != 0)
			{
				uint8_t i;

				/* Update stream properties to use composition values */

				for (i = 0; i < stream[1].current; ++i)
				{
					*dst_qc++ = PROPERTY_GET(compose_state.qc_index, compose_state.qc_data, *src_codepoint);
					*dst_ccc++ = *src_ccc++;
					*dst_codepoint++ = *src_codepoint++;
				}
			}
			else
			{
				/* Copy directly */

				memcpy(dst_codepoint, src_codepoint, stream[1].current * sizeof(unicode_t));
				memcpy(dst_qc, src_qc, stream[1].current * sizeof(uint8_t));
				memcpy(dst_ccc, src_ccc, stream[1].current * sizeof(uint8_t));
			}

			stream[2].current += stream[1].current;
			stream[2].filled += stream[1].current;
		}

		/* Decompose input sequence into next stream */

		finished = !decompose_execute(&decompose_state);
		if (!finished)
		{
			/* Output current stream it it could overflow accumulation buffer */

			write = (stream[1].current + stream[2].filled) >= STREAM_SAFE_MAX;
		}

		/* Reorder potentially unordered decomposed stream */

		if (!stream[1].stable)
		{
			stream_reorder(&stream[1]);
		}

		/* Write stream to output when overflowing or when accumulation buffer is empty*/

		if (write ||
			finished)
		{
			uint8_t i;

			/* Compose accumulation buffer */

			if ((flags & UTF8_NORMALIZE_COMPOSE) != 0 &&
				!compose_execute(&compose_state))
			{
				break;
			}

			/* Write to output buffer */

			for (i = 0; i < stream_output->current; ++i)
			{
				uint8_t encoded_size = codepoint_write(stream_output->codepoint[i], &dst, &dst_size);
				if (encoded_size == 0)
				{
					UTF8_SET_ERROR(NOT_ENOUGH_SPACE);

					return bytes_written;
				}

				bytes_written += encoded_size;
			}

			/* Reset accumulation buffer */

			stream[2].current = 0;
			stream[2].filled = 0;
		}
	}
	while (!finished);

	UTF8_SET_ERROR(NONE);

	return bytes_written;
}