1 /*
2 * Copyright (C) 2012 Oracle.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see http://www.gnu.org/copyleft/gpl.txt
16 */
17
18 #include "smatch.h"
19
20 static int my_id;
21
match_parameter(const char * fn,struct expression * expr,void * _param)22 static void match_parameter(const char *fn, struct expression *expr, void *_param)
23 {
24 int param = PTR_INT(_param);
25 struct expression *arg;
26 char *name;
27
28 arg = get_argument_from_call_expr(expr->args, param);
29 arg = strip_expr(arg);
30 if (!arg)
31 return;
32 if (arg->type != EXPR_COMPARE)
33 return;
34
35 name = expr_to_str_sym(arg, NULL);
36 sm_warning("expected a buffer size but got a comparison '%s'", name);
37 free_string(name);
38 }
39
register_funcs_from_file(void)40 static void register_funcs_from_file(void)
41 {
42 char name[256];
43 struct token *token;
44 const char *func;
45 char prev_func[256];
46 int size;
47
48 memset(prev_func, 0, sizeof(prev_func));
49 snprintf(name, 256, "%s.sizeof_param", option_project_str);
50 name[255] = '\0';
51 token = get_tokens_file(name);
52 if (!token)
53 return;
54 if (token_type(token) != TOKEN_STREAMBEGIN)
55 return;
56 token = token->next;
57 while (token_type(token) != TOKEN_STREAMEND) {
58 if (token_type(token) != TOKEN_IDENT)
59 break;
60 func = show_ident(token->ident);
61
62 token = token->next;
63 if (token_type(token) != TOKEN_NUMBER)
64 break;
65 size = atoi(token->number);
66
67 token = token->next;
68 if (token_type(token) == TOKEN_SPECIAL) {
69 if (token->special != '-')
70 break;
71 token = token->next;
72 }
73 if (token_type(token) != TOKEN_NUMBER)
74 break;
75 /* we don't care which argument hold the buf pointer */
76 token = token->next;
77
78 if (strcmp(func, prev_func) == 0)
79 continue;
80 strncpy(prev_func, func, 255);
81
82 add_function_hook(func, &match_parameter, INT_PTR(size));
83
84 }
85 if (token_type(token) != TOKEN_STREAMEND)
86 sm_perror("problem parsing '%s'", name);
87 clear_token_alloc();
88 }
89
check_wrong_size_arg(int id)90 void check_wrong_size_arg(int id)
91 {
92 my_id = id;
93 register_funcs_from_file();
94 }
95