buf_size: add a NULL check
[smatch.git] / smatch_data_source.c
blob8fe3d20ae44ee2c4a007e5894456a0806e13eaf2
1 /*
2 * smatch/smatch_data_source.c
4 * Copyright (C) 2013 Oracle.
6 * Licensed under the Open Software License version 1.1
8 */
10 #include "smatch.h"
11 #include "smatch_slist.h"
12 #include "smatch_extra.h"
14 static int my_id;
16 static char *get_source_parameter(struct expression *expr)
18 struct symbol *sym;
19 char *name;
20 int param;
21 struct sm_state *orig, *cur;
22 char *ret = NULL;
23 char buf[32];
25 name = expr_to_var_sym(expr, &sym);
26 if (!name || !sym)
27 goto out;
28 param = get_param_num_from_sym(sym);
29 if (param < 0)
30 goto out;
31 cur = get_sm_state(SMATCH_EXTRA, name, sym);
32 if (!cur)
33 goto out;
34 orig = get_sm_state_slist(get_start_states(), SMATCH_EXTRA, name, sym);
35 if (!orig)
36 goto out;
37 if (orig != cur)
38 goto out;
40 snprintf(buf, sizeof(buf), "p %d", param);
41 ret = alloc_string(buf);
43 out:
44 free_string(name);
45 return ret;
48 static char *get_source_assignment(struct expression *expr)
50 struct expression *right;
51 char *name;
52 char buf[64];
53 char *ret;
55 right = get_assigned_expr(expr);
56 right = strip_expr(right);
57 if (!right)
58 return NULL;
59 if (right->type != EXPR_CALL || right->fn->type != EXPR_SYMBOL)
60 return NULL;
61 if (is_fake_call(right))
62 return NULL;
63 name = expr_to_str(right->fn);
64 if (!name)
65 return NULL;
66 snprintf(buf, sizeof(buf), "r %s", name);
67 ret = alloc_string(buf);
68 free_string(name);
69 return ret;
72 static char *get_source_str(struct expression *expr)
74 char *source;
76 source = get_source_parameter(expr);
77 if (source)
78 return source;
79 return get_source_assignment(expr);
82 static void match_caller_info(struct expression *expr)
84 struct expression *tmp;
85 char *source;
86 int i;
88 i = -1;
89 FOR_EACH_PTR(expr->args, tmp) {
90 i++;
91 source = get_source_str(tmp);
92 if (!source)
93 continue;
94 sql_insert_caller_info(expr, DATA_SOURCE, i, "$$", source);
95 free_string(source);
96 } END_FOR_EACH_PTR(tmp);
99 void register_data_source(int id)
101 if (!option_info)
102 return;
103 my_id = id;
104 add_hook(&match_caller_info, FUNCTION_CALL_HOOK);