From 9e313368449e99458a020ed489e295b89f7cf75a Mon Sep 17 00:00:00 2001 From: Dustin Graves Date: Tue, 8 Mar 2016 14:42:59 -0700 Subject: layers: Add string array parameter checking The param_checker layer had previously peformed a NULL check on the pointer to a string array, but had not performed a NULL check for the individual strings in the array. This adds NULL checks for the individual strings. Change-Id: Id4527f670086187e8cd1f146027bfdfd1e134b7b --- generator.py | 3 +- layers/param_checker_utils.h | 80 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 74 insertions(+), 9 deletions(-) diff --git a/generator.py b/generator.py index 5dc3c9a8..efb46fbc 100644 --- a/generator.py +++ b/generator.py @@ -3134,7 +3134,8 @@ class ParamCheckerOutputGenerator(OutputGenerator): # If count and array parameters are optional, there # will be no validation if req == 'VK_TRUE' or cvReq == 'VK_TRUE': - checkExpr = 'skipCall |= validate_array(report_data, {}, "{ln}", {dn}, {pf}{ln}, {pf}{vn}, {}, {});\n'.format(name, cvReq, req, ln=lenParam.name, dn=valueDisplayName, vn=value.name, pf=valuePrefix) + funcName = 'validate_array' if value.type != 'char' else 'validate_string_array' + checkExpr = 'skipCall |= {}(report_data, {}, "{ln}", {dn}, {pf}{ln}, {pf}{vn}, {}, {});\n'.format(funcName, name, cvReq, req, ln=lenParam.name, dn=valueDisplayName, vn=value.name, pf=valuePrefix) elif not value.isoptional: # Function pointers need a reinterpret_cast to void* if value.type[:4] == 'PFN_': diff --git a/layers/param_checker_utils.h b/layers/param_checker_utils.h index ca5ca95d..d6058c82 100644 --- a/layers/param_checker_utils.h +++ b/layers/param_checker_utils.h @@ -71,10 +71,9 @@ VkBool32 validate_required_pointer( * * Verify that required count and array parameters are not NULL. If count * is not NULL and its value is not optional, verify that it is not 0. If the - * array parameter is optional and it is NULL, no verification is perforemd. - * If the array parameter is not optional and it is NULL, verify that the count - * is 0. The array parameter will normally be optional for this case (where - * count is a pointer), allowing the caller to retrieve the available count. + * array parameter is NULL, and it is not optional, verify that count is 0. + * The array parameter will typically be optional for this case (where count is + * a pointer), allowing the caller to retrieve the available count. * * @param report_data debug_report_data object for routing validation messages. * @param apiName Name of API call being validated. @@ -121,10 +120,9 @@ VkBool32 validate_array( /** * Validate array count and pointer to array. * - * Verify that required count parameters are not NULL. If the array parameter - * is NULL, verify that count is 0. If the array parameter is optional and it - * is NULL, no verification is perforemd. If the array parameter is not - * optional and it is NULL, verify that the count is 0. + * Verify that required count and array parameters are not 0 or NULL. If the + * count parameter is not optional, verify that it is not 0. If the array + * parameter is NULL, and it is not optional, verify that count is 0. * * @param report_data debug_report_data object for routing validation messages. * @param apiName Name of API call being validated. @@ -336,4 +334,70 @@ VkBool32 validate_struct_type_array( return skipCall; } +/** + * Validate string array count and content. + * + * Verify that required count and array parameters are not 0 or NULL. If the + * count parameter is not optional, verify that it is not 0. If the array + * parameter is NULL, and it is not optional, verify that count is 0. If the + * array parameter is not NULL, verify that none of the strings are NULL. + * + * @param report_data debug_report_data object for routing validation messages. + * @param apiName Name of API call being validated. + * @param countName Name of count parameter. + * @param arrayName Name of array parameter. + * @param count Number of strings in the array. + * @param array Array of strings to validate. + * @param countRequired The 'count' parameter may not be 0 when true. + * @param arrayRequired The 'array' parameter may not be NULL when true. + * @return Boolean value indicating that the call should be skipped. + */ +static +VkBool32 validate_string_array( + debug_report_data* report_data, + const char* apiName, + const char* countName, + const char* arrayName, + uint32_t count, + const char* const* array, + VkBool32 countRequired, + VkBool32 arrayRequired) +{ + VkBool32 skipCall = VK_FALSE; + + if ((count == 0) || (array == NULL)) { + // Count parameters not tagged as optional cannot be 0 + if ((count == 0) && (countRequired == VK_TRUE)) { + skipCall |= log_msg( + report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, + (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, + "PARAMCHECK", "%s: parameter %s must be greater than 0", + apiName, countName); + } + + // Array parameters not tagged as optional cannot be NULL, + // unless the count is 0 + if ((array == NULL) && (arrayRequired == VK_TRUE) && (count != 0)) { + skipCall |= log_msg( + report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, + (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, + "PARAMCHECK", "%s: required parameter %s specified as NULL", + apiName, arrayName); + } + } else { + // Verify that strings in the array not NULL + for (uint32_t i = 0; i < count; ++i) { + if (array[i] == NULL) { + skipCall |= log_msg( + report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, + (VkDebugReportObjectTypeEXT)0, 0, __LINE__, 1, + "PARAMCHECK", "%s: required parameter %s[%d] specified as NULL", + apiName, arrayName, i); + } + } + } + + return skipCall; +} + #endif // PARAM_CHECKER_UTILS_H -- cgit v1.2.3