OpenVAS Libraries  9.0.3
nasl_func.c
Go to the documentation of this file.
1 /* Nessus Attack Scripting Language
2  *
3  * Copyright (C) 2002 - 2004 Tenable Network Security
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2,
7  * as published by the Free Software Foundation
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, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  */
19 
20 #include <search.h> /* for qsort, lfind */
21 #include <stdlib.h> /* for free */
22 #include <string.h> /* for strcmp */
23 
24 #include <glib.h> /* for g_free */
25 
26 #include "nasl_tree.h"
27 #include "nasl_global_ctxt.h"
28 #include "nasl_func.h"
29 #include "nasl_var.h"
30 #include "nasl_lex_ctxt.h"
31 #include "exec.h"
32 
33 #include "nasl_debug.h"
34 
36 static int
37 hash_str (const char *s)
38 {
39  return hash_str2 (s, FUNC_NAME_HASH);
40 }
41 
46 static nasl_func *
47 get_func (lex_ctxt * ctxt, const char *name, int h)
48 {
49  nasl_func *v;
50  lex_ctxt *c;
51 
52  for (c = ctxt; c != NULL; c = c->up_ctxt)
53  {
54  for (v = c->functions[h]; v != NULL; v = v->next_func)
55  if (v->func_name != NULL && strcmp (name, v->func_name) == 0)
56  return v;
57  }
58 
59  return NULL;
60 }
61 
62 typedef int(*qsortcmp)(const void *, const void *);
63 
64 nasl_func *
65 insert_nasl_func (lex_ctxt * lexic, const char *fname, tree_cell * decl_node)
66 {
67  int h = hash_str (fname);
68  int i;
69  nasl_func *pf;
70  tree_cell *pc;
71 
72  if (get_func (lexic, fname, h) != NULL)
73  {
74  nasl_perror (lexic,
75  "insert_nasl_func: function '%s' is already defined\n",
76  fname);
77  return NULL;
78  }
79  pf = g_malloc0 (sizeof (nasl_func));
80  pf->func_name = g_strdup (fname);
81 
82  if (decl_node != NULL && decl_node != FAKE_CELL)
83  {
84  for (pc = decl_node->link[0]; pc != NULL; pc = pc->link[0])
85  if (pc->x.str_val == NULL)
86  pf->nb_unnamed_args++;
87  else
88  pf->nb_named_args++;
89 
90  pf->args_names = g_malloc0 (sizeof (char *) * pf->nb_named_args);
91  for (i = 0, pc = decl_node->link[0]; pc != NULL; pc = pc->link[0])
92  if (pc->x.str_val != NULL)
93  pf->args_names[i++] = g_strdup (pc->x.str_val);
94  /* Sort argument names */
95  qsort (pf->args_names, pf->nb_named_args, sizeof (pf->args_names[0]),
96  (qsortcmp)strcmp);
97 
98  pf->block = decl_node->link[1];
99  ref_cell (pf->block);
100  }
101  /* Allow variable number of arguments for user defined functions */
102  if (decl_node != NULL)
103  pf->nb_unnamed_args = 9999;
104 
105  pf->next_func = lexic->functions[h];
106  lexic->functions[h] = pf;
107  return pf;
108 }
109 
110 tree_cell *
111 decl_nasl_func (lex_ctxt * lexic, tree_cell * decl_node)
112 {
113  if (decl_node == NULL || decl_node == FAKE_CELL)
114  {
115  nasl_perror (lexic, "Cannot insert NULL or FAKE cell as function\n");
116  return NULL;
117  }
118 
119  if (insert_nasl_func (lexic, decl_node->x.str_val, decl_node) == NULL)
120  return NULL;
121  else
122  return FAKE_CELL;
123 }
124 
125 nasl_func *
126 get_func_ref_by_name (lex_ctxt * ctxt, const char *name)
127 {
128  int h = hash_str (name);
129  nasl_func *f;
130 
131  if ((f = get_func (ctxt, name, h)) != NULL)
132  return f;
133  else
134  return NULL;
135 }
136 
137 static int
138 stringcompare (const void *a, const void *b)
139 {
140  char **s1 = (char **) a, **s2 = (char **) b;
141  return strcmp (*s1, *s2);
142 }
143 
144 extern FILE *nasl_trace_fp;
145 
146 tree_cell *
147 nasl_func_call (lex_ctxt * lexic, const nasl_func * f, tree_cell * arg_list)
148 {
149 #if 0
150  return FAKE_CELL;
151 #else
152  int nb_u = 0, nb_n = 0, nb_a = 0;
153  tree_cell *pc = NULL, *pc2 = NULL, *retc = NULL;
154  lex_ctxt *lexic2 = NULL;
155  char *trace_buf = NULL;
156  char *temp_funname = NULL, *tmp_filename = NULL;
157  int trace_buf_len = 0, tn;
158 #define TRACE_BUF_SZ 255
159 
160 #if 0
161  nasl_dump_tree (arg_list);
162 #endif
163 
164  /* 1. Create a new context */
165  lexic2 = init_empty_lex_ctxt ();
166  lexic2->script_infos = lexic->script_infos;
167  lexic2->oid = lexic->oid;
168  lexic2->recv_timeout = lexic->recv_timeout;
169  lexic2->fct_ctxt = 1;
170 
171  if (nasl_trace_fp != NULL)
172  {
173  trace_buf = g_malloc0 (TRACE_BUF_SZ);
174  tn = snprintf (trace_buf, TRACE_BUF_SZ, "Call %s(", f->func_name);
175  if (tn > 0)
176  trace_buf_len += tn;
177  }
178 
179  if (!(f->flags & FUNC_FLAG_COMPAT))
180  {
181  for (pc = arg_list; pc != NULL; pc = pc->link[1])
182  if (pc->x.str_val == NULL)
183  nb_u++;
184  else
185  {
186  size_t num = f->nb_named_args;
187  if (lfind
188  (&pc->x.str_val, f->args_names, &num, sizeof (char *),
189  stringcompare) != NULL)
190  nb_n++;
191  }
192 
193  if (nb_n + nb_u > f->nb_unnamed_args + f->nb_named_args)
194  nasl_perror (lexic,
195  "Too many args for function '%s' [%dN+%dU > %dN+%dU]\n",
196  f->func_name, nb_n, nb_u, f->nb_unnamed_args,
197  f->nb_named_args);
198  /*
199  * I should look exactly how unnamed arguments works...
200  * Or maybe I should remove this feature?
201  */
202 
203  for (nb_u = 0, pc = arg_list; pc != NULL; pc = pc->link[1])
204  {
205 #if 0
206  pc2 = pc->link[0];
207  ref_cell (pc2);
208  do
209  {
210  pc22 = nasl_exec (lexic, pc2);
211  deref_cell (pc2);
212  pc2 = pc22;
213  }
214  while (!nasl_is_leaf (pc2));
215 #else
216  pc2 = cell2atom (lexic, pc->link[0]);
217 #endif
218  if (pc->x.str_val == NULL)
219  {
220  /* 2. Add unnamed (numbered) variables for unnamed args */
221  if (add_numbered_var_to_ctxt (lexic2, nb_u, pc2) == NULL)
222  goto error;
223  nb_u++;
224  if (nasl_trace_fp != NULL && trace_buf_len < TRACE_BUF_SZ)
225  {
226  tn = snprintf (trace_buf + trace_buf_len,
227  TRACE_BUF_SZ - trace_buf_len, "%s%d: %s",
228  nb_a > 0 ? ", " : "", nb_u,
229  dump_cell_val (pc2));
230  if (tn > 0)
231  trace_buf_len += tn;
232  }
233  nb_a++;
234  }
235  else
236  {
237  /* 3. and add named variables for named args */
238  if (add_named_var_to_ctxt (lexic2, pc->x.str_val, pc2) == NULL)
239  goto error;
240  if (nasl_trace_fp != NULL && trace_buf_len < TRACE_BUF_SZ)
241  {
242  tn = snprintf (trace_buf + trace_buf_len,
243  TRACE_BUF_SZ - trace_buf_len, "%s%s: %s",
244  nb_a > 0 ? ", " : "", pc->x.str_val,
245  dump_cell_val (pc2));
246  if (tn > 0)
247  trace_buf_len += tn;
248  }
249  nb_a++;
250  }
251  deref_cell (pc2);
252  }
253 
254  if (nasl_trace_fp != NULL)
255  {
256  if (trace_buf_len < TRACE_BUF_SZ)
257  nasl_trace (lexic, "NASL> %s)\n", trace_buf);
258  else
259  nasl_trace (lexic, "NASL> %s ...)\n", trace_buf);
260  g_free (trace_buf);
261  }
262 
263  /* 4. Chain new context to old (lexic) */
264  lexic2->up_ctxt = lexic;
265  /* 5. Execute */
266  tmp_filename = g_strdup (nasl_get_filename (NULL));
268  if (f->flags & FUNC_FLAG_INTERNAL)
269  {
270  tree_cell *(*pf2) (lex_ctxt *) = f->block;
271  retc = pf2 (lexic2);
272  }
273  else
274  {
275  temp_funname = g_strdup (nasl_get_function_name());
277  retc = nasl_exec (lexic2, f->block);
278  deref_cell (retc);
279  retc = FAKE_CELL;
280  nasl_set_function_name (temp_funname);
281  g_free (temp_funname);
282  }
283 
284  nasl_set_filename (tmp_filename);
285  g_free (tmp_filename);
286  if ((retc == NULL || retc == FAKE_CELL)
287  && (lexic2->ret_val != NULL && lexic2->ret_val != FAKE_CELL))
288  {
289 #if 0
290  nasl_perror (lexic,
291  "nasl_func_call: nasl_exec(%s) returns NULL or FAKE value, but context disagrees. Fixing...\n",
292  f->func_name);
293  nasl_dump_tree (retc);
294 #endif
295  retc = lexic2->ret_val;
296  ref_cell (retc);
297  }
298 
299  if (nasl_trace_enabled ())
300  nasl_trace (lexic, "NASL> Return %s: %s\n", f->func_name,
301  dump_cell_val (retc));
302 #if 1
303  if (!nasl_is_leaf (retc))
304  {
305  nasl_perror (lexic,
306  "nasl_func_call: return value from %s is not atomic!\n",
307  f->func_name);
308  nasl_dump_tree (retc);
309  }
310 #endif
311 
312  free_lex_ctxt (lexic2);
313  lexic2 = NULL;
314  return retc;
315  }
316 
317 
318 error:
319  free_lex_ctxt (lexic2);
320  return NULL;
321 #endif
322 }
323 
324 tree_cell *
326 {
327  tree_cell *c;
328 
329  retv = cell2atom (ctxt, retv);
330  if (retv == NULL)
331  retv = FAKE_CELL;
332 
333  if (retv != FAKE_CELL && retv->type == REF_ARRAY)
334  /* We have to "copy" it as the referenced array will be freed */
335  {
336  c = copy_ref_array (retv);
337  deref_cell (retv);
338  retv = c;
339  }
340 
341  while (ctxt != NULL)
342  {
343  ctxt->ret_val = retv;
344  ref_cell (retv);
345  if (ctxt->fct_ctxt)
346  break;
347  ctxt = ctxt->up_ctxt;
348  }
349  /* Bug? Do not return NULL, as we may test it to break the control flow */
350  deref_cell (retv);
351  return FAKE_CELL;
352 }
353 
354 static void
355 free_func (nasl_func * f)
356 {
357  int i;
358 
359  if (! f) return;
360 
361  g_free (f->func_name);
362 
363  if (!(f->flags & FUNC_FLAG_INTERNAL))
364  {
365  for (i = 0; i < f->nb_named_args; i++)
366  g_free (f->args_names[i]);
367  g_free (f->args_names);
368  deref_cell (f->block);
369  }
370  g_free (f);
371 }
372 
373 
374 void
376 {
377  if (f == NULL)
378  return;
380  free_func (f);
381 }
tree_cell * nasl_return(lex_ctxt *ctxt, tree_cell *retv)
Definition: nasl_func.c:325
int nasl_trace_enabled(void)
Checks if the nasl_trace_fp is set.
Definition: nasl_debug.c:151
#define FAKE_CELL
Definition: nasl_tree.h:120
void * block
Definition: nasl_func.h:36
struct TC * link[4]
Definition: nasl_tree.h:117
const char * nasl_get_filename(const char *function)
Definition: nasl_debug.c:43
void ref_cell(tree_cell *c)
Definition: nasl_tree.c:188
FILE * nasl_trace_fp
Definition: exec.c:386
tree_cell * copy_ref_array(const tree_cell *c1)
Definition: nasl_var.c:566
short type
Definition: nasl_tree.h:107
char * str_val
Definition: nasl_tree.h:113
void nasl_dump_tree(const tree_cell *c)
Definition: nasl_tree.c:439
tree_cell * cell2atom(lex_ctxt *lexic, tree_cell *c1)
Definition: exec.c:216
void deref_cell(tree_cell *c)
Definition: nasl_tree.c:202
#define FUNC_NAME_HASH
Definition: nasl_func.h:22
char * func_name
Definition: nasl_func.h:32
struct st_nasl_func * next_func
Definition: nasl_func.h:38
void nasl_set_filename(const char *filename)
Definition: nasl_debug.c:71
char ** args_names
Definition: nasl_func.h:35
const char * nasl_get_function_name()
Definition: nasl_debug.c:65
int nb_named_args
Definition: nasl_func.h:34
union TC::@7 x
#define FUNC_FLAG_COMPAT
Definition: nasl_func.h:24
void free_lex_ctxt(lex_ctxt *c)
Definition: nasl_lex_ctxt.c:46
void nasl_trace(lex_ctxt *lexic, char *msg,...)
Prints debug message in printf fashion to nasl_trace_fp if it exists.
Definition: nasl_debug.c:165
nasl_func * insert_nasl_func(lex_ctxt *lexic, const char *fname, tree_cell *decl_node)
Definition: nasl_func.c:65
nasl_func * functions[FUNC_NAME_HASH]
Definition: nasl_lex_ctxt.h:46
#define FUNC_FLAG_INTERNAL
Definition: nasl_func.h:25
lex_ctxt * init_empty_lex_ctxt()
Definition: nasl_lex_ctxt.c:29
int nasl_is_leaf(const tree_cell *pc)
Definition: nasl_tree.c:463
named_nasl_var * add_named_var_to_ctxt(lex_ctxt *, const char *, tree_cell *)
Definition: nasl_var.c:908
Definition: nasl_tree.h:105
char * dump_cell_val(const tree_cell *c)
Definition: nasl_tree.c:301
unsigned fct_ctxt
Definition: nasl_lex_ctxt.h:35
const char * name
Definition: nasl_init.c:524
#define TRACE_BUF_SZ
int nb_unnamed_args
Definition: nasl_func.h:34
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition: nasl_debug.c:94
tree_cell * nasl_func_call(lex_ctxt *lexic, const nasl_func *f, tree_cell *arg_list)
Definition: nasl_func.c:147
void free_func_chain(nasl_func *f)
Definition: nasl_func.c:375
void nasl_set_function_name(const char *funname)
Definition: nasl_debug.c:56
tree_cell * ret_val
Definition: nasl_lex_ctxt.h:34
anon_nasl_var * add_numbered_var_to_ctxt(lex_ctxt *, int, tree_cell *)
Definition: nasl_var.c:876
int hash_str2(const char *s, int n)
Definition: nasl_var.c:51
const char * oid
Definition: nasl_lex_ctxt.h:40
struct arglist * script_infos
Definition: nasl_lex_ctxt.h:39
int(* qsortcmp)(const void *, const void *)
Definition: nasl_func.c:62
nasl_func * get_func_ref_by_name(lex_ctxt *ctxt, const char *name)
Definition: nasl_func.c:126
tree_cell * nasl_exec(lex_ctxt *lexic, tree_cell *st)
Execute a parse tree.
Definition: exec.c:800
struct struct_lex_ctxt * up_ctxt
Definition: nasl_lex_ctxt.h:33
tree_cell * decl_nasl_func(lex_ctxt *lexic, tree_cell *decl_node)
Definition: nasl_func.c:111