Print this page
11506 smatch resync

*** 245,254 **** --- 245,286 ---- if (get_terminated_state(expr) == &terminated) return 1; return 0; } + static void match_strnlen_test(struct expression *expr) + { + struct expression *left, *tmp, *arg; + int cnt; + + if (expr->type != EXPR_COMPARE) + return; + if (expr->op != SPECIAL_EQUAL && expr->op != SPECIAL_NOTEQUAL) + return; + + left = strip_expr(expr->left); + cnt = 0; + while ((tmp = get_assigned_expr(left))) { + if (cnt++ > 3) + break; + left = tmp; + } + + if (left->type != EXPR_CALL) + return; + if (!sym_name_is("strnlen", left->fn)) + return; + arg = get_argument_from_call_expr(left->args, 0); + set_true_false_states_expr(my_id, arg, + (expr->op == SPECIAL_EQUAL) ? &terminated : NULL, + (expr->op == SPECIAL_NOTEQUAL) ? &terminated : NULL); + if (get_param_num(arg) >= 0) + set_true_false_states_expr(param_set_id, arg, + (expr->op == SPECIAL_EQUAL) ? &terminated : NULL, + (expr->op == SPECIAL_NOTEQUAL) ? &terminated : NULL); + } + void register_nul_terminator(int id) { my_id = id; add_hook(&match_nul_assign, ASSIGNMENT_HOOK);
*** 258,267 **** --- 290,301 ---- add_member_info_callback(my_id, struct_member_callback); add_split_return_callback(&split_return_info); select_caller_info_hook(caller_info_terminated, TERMINATED); select_return_states_hook(TERMINATED, return_info_terminated); + + add_hook(&match_strnlen_test, CONDITION_HOOK); } void register_nul_terminator_param_set(int id) { param_set_id = id;