diff options
Diffstat (limited to 'builtin.c')
| -rw-r--r-- | builtin.c | 25 |
1 files changed, 24 insertions, 1 deletions
@@ -29,6 +29,7 @@ #include "expand.h" #include "symbol.h" #include "compat/bswap.h" +#include "string.h" #include <stdarg.h> #define dyntype incomplete_ctype @@ -596,6 +597,28 @@ static struct symbol_op object_size_op = { .expand = expand_object_size, }; +static int expand_strlen(struct expression *expr, int cost) +{ + struct expression *arg = first_expression(expr->args); + + if (!arg) + return UNSAFE; + if (arg->type == EXPR_SYMBOL) + arg = arg->symbol->initializer; + if (!arg || arg->type != EXPR_STRING || !arg->string->length) + return UNSAFE; + + expr->flags |= CEF_SET_ICE; + expr->type = EXPR_VALUE; + expr->value = strlen(arg->string->data); + expr->taint = 0; + return 0; +} + +static struct symbol_op strlen_op = { + .expand = expand_strlen, +}; + /* * Builtin functions */ @@ -775,7 +798,7 @@ static const struct builtin_fn builtins_common[] = { { "__builtin_strcpy", &string_ctype, 0, { &string_ctype, &const_string_ctype }}, { "__builtin_strcspn", size_t_ctype, 0, { &const_string_ctype, &const_string_ctype }}, { "__builtin_strdup", &string_ctype, 0, { &const_string_ctype }}, - { "__builtin_strlen", size_t_ctype, 0, { &const_string_ctype }}, + { "__builtin_strlen", size_t_ctype, 0, { &const_string_ctype }, .op = &strlen_op}, { "__builtin_strncasecmp", &int_ctype, 0, { &const_string_ctype, &const_string_ctype, size_t_ctype }}, { "__builtin_strncat", &string_ctype, 0, { &string_ctype, &const_string_ctype, size_t_ctype }}, { "__builtin_strncmp", &int_ctype, 0, { &const_string_ctype, &const_string_ctype, size_t_ctype }}, |
