From 19e65b4732bd6d1df86ce84949f3fc0fbe84197b Mon Sep 17 00:00:00 2001 From: Mark Lobodzinski Date: Mon, 11 Jan 2016 14:17:05 -0700 Subject: [PATCH] layers: Add UTF-8 String validation utility --- layers/vk_layer_utils.cpp | 45 +++++++++++++++++++++++++++++++++++++++ layers/vk_layer_utils.h | 7 ++++++ 2 files changed, 52 insertions(+) diff --git a/layers/vk_layer_utils.cpp b/layers/vk_layer_utils.cpp index db433dc7..2452b0ec 100644 --- a/layers/vk_layer_utils.cpp +++ b/layers/vk_layer_utils.cpp @@ -601,3 +601,48 @@ VkDeviceSize vk_safe_modulo(VkDeviceSize dividend, VkDeviceSize divisor) } +static const char UTF8_ONE_BYTE_CODE = 0xC0; +static const char UTF8_ONE_BYTE_MASK = 0xE0; +static const char UTF8_TWO_BYTE_CODE = 0xE0; +static const char UTF8_TWO_BYTE_MASK = 0xF0; +static const char UTF8_THREE_BYTE_CODE = 0xF0; +static const char UTF8_THREE_BYTE_MASK = 0xF8; +static const char UTF8_DATA_BYTE_CODE = 0x80; +static const char UTF8_DATA_BYTE_MASK = 0xC0; + +VkStringErrorFlags vk_string_validate(const int max_length, char *utf8) +{ + VkStringErrorFlags result = VK_STRING_ERROR_NONE; + int code; + int num_char_bytes; + int i,j; + + for (i = 0; i < max_length; i++) + { + if (utf8[i] == 0) { + break; + } else if ((utf8[i] > 0x20) && (utf8[i] < 0x7f)) { + num_char_bytes = 0; + } else if ((utf8[i] & UTF8_ONE_BYTE_MASK) == UTF8_ONE_BYTE_CODE) { + num_char_bytes = 1; + } else if ((utf8[i] & UTF8_TWO_BYTE_MASK) == UTF8_TWO_BYTE_CODE) { + num_char_bytes = 2; + } else if ((utf8[i] & UTF8_THREE_BYTE_MASK) == UTF8_THREE_BYTE_CODE) { + num_char_bytes = 3; + } else { + result = VK_STRING_ERROR_BAD_DATA; + } + + // Validate the following num_char_bytes of data + for (j = 0; (j < num_char_bytes) && (i < max_length); j++) { + if (++i == max_length) { + result |= VK_STRING_ERROR_LENGTH; + break; + } + if ((utf8[i] & UTF8_DATA_BYTE_MASK) != UTF8_DATA_BYTE_CODE) { + result |= VK_STRING_ERROR_BAD_DATA; + } + } + } + return result; +} diff --git a/layers/vk_layer_utils.h b/layers/vk_layer_utils.h index 9c443284..41b78758 100644 --- a/layers/vk_layer_utils.h +++ b/layers/vk_layer_utils.h @@ -90,6 +90,12 @@ typedef enum VkFormatCompatibilityClass { VK_FORMAT_COMPATIBILITY_CLASS_MAX_ENUM = 45 } VkFormatCompatibilityClass; +typedef enum VkStringErrorFlagBits { + VK_STRING_ERROR_NONE = 0x00000000, + VK_STRING_ERROR_LENGTH = 0x00000001, + VK_STRING_ERROR_BAD_DATA = 0x00000002, +} VkStringErrorFlagBits; +typedef VkFlags VkStringErrorFlags; static inline bool vk_format_is_undef(VkFormat format) { @@ -117,6 +123,7 @@ size_t vk_format_get_size(VkFormat format); unsigned int vk_format_get_channel_count(VkFormat format); VkFormatCompatibilityClass vk_format_get_compatibility_class(VkFormat format); VkDeviceSize vk_safe_modulo(VkDeviceSize dividend, VkDeviceSize divisor); +VkStringErrorFlags vk_string_validate(const int max_length, char *char_array); static inline int u_ffs(int val) { -- 2.34.1