Simplify parsing of integers in .datax files
In the .datax parser, since we're calling strtol() anyway, rely on it for verification. This makes the .datax parser very slightly more liberal (leading spaces and '+' are now accepted), and changes the interpretation of numbers with leading zeros to octal. Before, an argument like :0123: was parsed as decimal, but an argument like :0123+1: was parsed as a C expression and hence the leading zero marked an octal representation. Now, a leading zero is always interpreted according to C syntax, namely indicating octal. There are no nonzero integer constants with a leading zero in a .data file, so this does not affect existing test cases. In the .datax generator, allow negative arguments to be 'int' (before, they were systematically treated as 'exp' even though they didn't need to be). In the .datax parser, validate the range of integer constants. They have to fit in int32_t. In the .datax generator, use 'exp' instead of 'int' for integer constants that are out of range. Signed-off-by: Gilles Peskine <Gilles.Peskine@arm.com>
This commit is contained in:
parent
a9946952b4
commit
5226eb5cd3
3 changed files with 30 additions and 40 deletions
|
@ -846,6 +846,14 @@ def write_dependencies(out_data_f, test_dependencies, unique_dependencies):
|
|||
return dep_check_code
|
||||
|
||||
|
||||
INT_VAL_REGEX = re.compile(r'-?(\d+|0x[0-9a-f]+)$', re.I)
|
||||
def val_is_int(val: str) -> bool:
|
||||
"""Whether val is suitable as an 'int' parameter in the .datax file."""
|
||||
if not INT_VAL_REGEX.match(val):
|
||||
return False
|
||||
# Limit the range to what is guaranteed to get through strtol()
|
||||
return abs(int(val, 0)) <= 0x7fffffff
|
||||
|
||||
def write_parameters(out_data_f, test_args, func_args, unique_expressions):
|
||||
"""
|
||||
Writes test parameters to the intermediate data file, replacing
|
||||
|
@ -864,9 +872,9 @@ def write_parameters(out_data_f, test_args, func_args, unique_expressions):
|
|||
typ = func_args[i]
|
||||
val = test_args[i]
|
||||
|
||||
# check if val is a non literal int val (i.e. an expression)
|
||||
if typ == 'int' and not re.match(r'(\d+|0x[0-9a-f]+)$',
|
||||
val, re.I):
|
||||
# Pass small integer constants literally. This reduces the size of
|
||||
# the C code. Register anything else as an expression.
|
||||
if typ == 'int' and not val_is_int(val):
|
||||
typ = 'exp'
|
||||
if val not in unique_expressions:
|
||||
unique_expressions.append(val)
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <test/bignum_helpers.h>
|
||||
#include <test/psa_crypto_helpers.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -32,46 +32,26 @@ int verify_string(char **str)
|
|||
*
|
||||
* \return 0 if success else 1
|
||||
*/
|
||||
int verify_int(char *str, int32_t *value)
|
||||
int verify_int(char *str, int32_t *p_value)
|
||||
{
|
||||
size_t i;
|
||||
int minus = 0;
|
||||
int digits = 1;
|
||||
int hex = 0;
|
||||
|
||||
for (i = 0; i < strlen(str); i++) {
|
||||
if (i == 0 && str[i] == '-') {
|
||||
minus = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (((minus && i == 2) || (!minus && i == 1)) &&
|
||||
str[i - 1] == '0' && (str[i] == 'x' || str[i] == 'X')) {
|
||||
hex = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!((str[i] >= '0' && str[i] <= '9') ||
|
||||
(hex && ((str[i] >= 'a' && str[i] <= 'f') ||
|
||||
(str[i] >= 'A' && str[i] <= 'F'))))) {
|
||||
digits = 0;
|
||||
break;
|
||||
}
|
||||
char *end = NULL;
|
||||
errno = 0;
|
||||
long value = strtol(str, &end, 0);
|
||||
if (errno == EINVAL || *end != '\0') {
|
||||
mbedtls_fprintf(stderr,
|
||||
"Expected integer for parameter and got: %s\n", str);
|
||||
return KEY_VALUE_MAPPING_NOT_FOUND;
|
||||
}
|
||||
|
||||
if (digits) {
|
||||
if (hex) {
|
||||
*value = strtol(str, NULL, 16);
|
||||
} else {
|
||||
*value = strtol(str, NULL, 10);
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (errno == ERANGE
|
||||
#if LONG_MAX > 0x7fffffff
|
||||
|| value > 0x7fffffffL || value < -0x80000000L
|
||||
#endif
|
||||
) {
|
||||
mbedtls_fprintf(stderr, "Integer out of range: %s\n", str);
|
||||
return KEY_VALUE_MAPPING_NOT_FOUND;
|
||||
}
|
||||
|
||||
mbedtls_fprintf(stderr,
|
||||
"Expected integer for parameter and got: %s\n", str);
|
||||
return KEY_VALUE_MAPPING_NOT_FOUND;
|
||||
*p_value = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue