230 if (!arg)
231 return;
232 }
233
234 name = get_variable_from_key(arg, key, &sym);
235 if (!name || !sym)
236 goto free;
237
238 set_terminated_var_sym(name, sym, (*value == '1') ? &terminated : &unterminated);
239 free:
240 free_string(name);
241 }
242
243 bool is_nul_terminated(struct expression *expr)
244 {
245 if (get_terminated_state(expr) == &terminated)
246 return 1;
247 return 0;
248 }
249
250 void register_nul_terminator(int id)
251 {
252 my_id = id;
253
254 add_hook(&match_nul_assign, ASSIGNMENT_HOOK);
255 add_hook(&match_string_assign, ASSIGNMENT_HOOK);
256
257 add_hook(&match_call_info, FUNCTION_CALL_HOOK);
258 add_member_info_callback(my_id, struct_member_callback);
259 add_split_return_callback(&split_return_info);
260
261 select_caller_info_hook(caller_info_terminated, TERMINATED);
262 select_return_states_hook(TERMINATED, return_info_terminated);
263 }
264
265 void register_nul_terminator_param_set(int id)
266 {
267 param_set_id = id;
268 }
|
230 if (!arg)
231 return;
232 }
233
234 name = get_variable_from_key(arg, key, &sym);
235 if (!name || !sym)
236 goto free;
237
238 set_terminated_var_sym(name, sym, (*value == '1') ? &terminated : &unterminated);
239 free:
240 free_string(name);
241 }
242
243 bool is_nul_terminated(struct expression *expr)
244 {
245 if (get_terminated_state(expr) == &terminated)
246 return 1;
247 return 0;
248 }
249
250 static void match_strnlen_test(struct expression *expr)
251 {
252 struct expression *left, *tmp, *arg;
253 int cnt;
254
255 if (expr->type != EXPR_COMPARE)
256 return;
257 if (expr->op != SPECIAL_EQUAL && expr->op != SPECIAL_NOTEQUAL)
258 return;
259
260 left = strip_expr(expr->left);
261 cnt = 0;
262 while ((tmp = get_assigned_expr(left))) {
263 if (cnt++ > 3)
264 break;
265 left = tmp;
266 }
267
268 if (left->type != EXPR_CALL)
269 return;
270 if (!sym_name_is("strnlen", left->fn))
271 return;
272 arg = get_argument_from_call_expr(left->args, 0);
273 set_true_false_states_expr(my_id, arg,
274 (expr->op == SPECIAL_EQUAL) ? &terminated : NULL,
275 (expr->op == SPECIAL_NOTEQUAL) ? &terminated : NULL);
276 if (get_param_num(arg) >= 0)
277 set_true_false_states_expr(param_set_id, arg,
278 (expr->op == SPECIAL_EQUAL) ? &terminated : NULL,
279 (expr->op == SPECIAL_NOTEQUAL) ? &terminated : NULL);
280 }
281
282 void register_nul_terminator(int id)
283 {
284 my_id = id;
285
286 add_hook(&match_nul_assign, ASSIGNMENT_HOOK);
287 add_hook(&match_string_assign, ASSIGNMENT_HOOK);
288
289 add_hook(&match_call_info, FUNCTION_CALL_HOOK);
290 add_member_info_callback(my_id, struct_member_callback);
291 add_split_return_callback(&split_return_info);
292
293 select_caller_info_hook(caller_info_terminated, TERMINATED);
294 select_return_states_hook(TERMINATED, return_info_terminated);
295
296 add_hook(&match_strnlen_test, CONDITION_HOOK);
297 }
298
299 void register_nul_terminator_param_set(int id)
300 {
301 param_set_id = id;
302 }
|