layers: Add UTF-8 String validation utility
authorMark Lobodzinski <mark@lunarg.com>
Mon, 11 Jan 2016 21:17:05 +0000 (14:17 -0700)
committerMark Lobodzinski <mark@lunarg.com>
Mon, 8 Feb 2016 20:57:36 +0000 (13:57 -0700)
layers/vk_layer_utils.cpp
layers/vk_layer_utils.h

index db433dc..2452b0e 100644 (file)
@@ -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;
+}
index 9c44328..41b7875 100644 (file)
@@ -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)
 {