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