OpenVAS Scanner  22.7.9
lint.c
Go to the documentation of this file.
1 /* SPDX-FileCopyrightText: 2023 Greenbone AG
2  * SPDX-FileCopyrightText: 2004 Michel Arboi
3  *
4  * SPDX-License-Identifier: GPL-2.0-only
5  */
6 
7 #include "lint.h"
8 
9 #include "exec.h"
10 #include "nasl.h"
11 #include "nasl_debug.h"
12 #include "nasl_func.h"
13 #include "nasl_global_ctxt.h"
14 #include "nasl_init.h"
15 #include "nasl_lex_ctxt.h"
16 #include "nasl_tree.h"
17 #include "nasl_var.h"
18 
19 #include <stdio.h>
20 #include <string.h>
21 #include <unistd.h>
22 
23 #undef G_LOG_DOMAIN
24 
27 #define G_LOG_DOMAIN "lib nasl"
28 
32 typedef struct st_func_info
33 {
34  gchar *func_name;
35  gchar *caller_func;
36  gchar *caller_file;
38 
39 char *nasl_name;
40 
42 static void
44 {
45  errors_cnt = 0;
46 }
47 static void
49 {
50  errors_cnt++;
51  return;
52 }
53 static int
55 {
56  return errors_cnt;
57 }
58 
65 static void
67 {
68  g_free (data->func_name);
69  g_free (data->caller_func);
70  g_free (data->caller_file);
71  memset (data, '\0', sizeof (func_info));
72 }
73 
80 static void
81 add_predef_varname (GSList **defined_var)
82 {
83  int i;
84  gchar *keywords[] = {"ACT_UNKNOWN", "description", "NULL", "SCRIPT_NAME",
85  "COMMAND_LINE", "_FCT_ANON_ARGS", NULL};
86 
87  for (i = 0; keywords[i] != NULL; i++)
88  *defined_var = g_slist_prepend (*defined_var, keywords[i]);
89  add_nasl_library (defined_var);
90 }
91 
100 static gint
101 list_cmp1 (gconstpointer lelem, gconstpointer data)
102 {
103  if (data)
104  {
105  gchar *lala = g_strdup (((func_info *) lelem)->func_name);
106  return (g_strcmp0 (lala, data));
107  }
108  return -1;
109 }
110 
117 static gint
118 reverse_search (GSList **def_func_tree, GSList *finfo)
119 {
120  func_info *fdata = finfo->data;
121  GSList *finfo_aux;
122 
123  // The file name is the original file to be tested. It is not an include.
124  if (!g_strcmp0 (fdata->caller_file, nasl_name)
125  && !g_str_has_suffix (nasl_name, ".inc"))
126  return 1;
127 
128  // The function is it self.
129  if (!g_strcmp0 (fdata->func_name, fdata->caller_func))
130  return 0;
131 
132  // I go up in the tree of called and defined functions.
133  if ((finfo_aux = g_slist_find_custom (*def_func_tree, fdata->caller_func,
134  (GCompareFunc) list_cmp1))
135  != NULL)
136  if (reverse_search (def_func_tree, finfo_aux))
137  return 1;
138 
139  return 0;
140 }
141 
150 static gint
151 list_cmp (gconstpointer lelem, gconstpointer data)
152 {
153  if (data)
154  return (g_strcmp0 (lelem, data));
155  return -1;
156 }
157 
168 static void
169 check_called_files (gpointer key, gpointer value, GSList **unusedfiles)
170 {
171  if (key != NULL)
172  // only check for includes not for main file
173  if (nasl_get_include_order ((const char *) key) > 0
174  && g_strcmp0 (value, "YES") != 0)
175  *unusedfiles = g_slist_prepend (*unusedfiles, key);
176 }
177 
185 static void
186 print_uncall_files (gpointer filename, gpointer lexic)
187 {
188  if (filename != NULL)
189  {
190  nasl_perror (lexic, "The included file '%s' is never used.",
191  (char *) filename);
192  inc_errors_cnt ();
193  lexic = NULL;
194  }
195 }
196 
202 static tree_cell *
203 nasl_lint_def (lex_ctxt *lexic, tree_cell *st, int lint_mode,
204  GHashTable **include_files, GHashTable **func_fnames_tab,
205  gchar *err_fname, GSList **called_funcs, GSList **def_func_tree)
206 {
207  int i;
208  tree_cell *ret = FAKE_CELL;
209  char *incname = NULL;
210  gchar *tmp_filename = NULL;
211  nasl_func *pf;
212  static gchar *current_fun_def = NULL;
213 
214  if (st->type == NODE_FUN_CALL)
215  {
216  pf = get_func_ref_by_name (lexic, st->x.str_val);
217  if (pf == NULL)
218  {
219  g_hash_table_insert (*func_fnames_tab, g_strdup (st->x.str_val),
220  g_strdup (err_fname));
221  }
222 
223  /* Save in a list the name of the called function, the file where it
224  is called from, and the function where it is called from. This will
225  help to know if a called function is really needed, or it was just
226  called by another defined function which is never called. */
227  func_info *finfo = g_malloc0 (sizeof (func_info));
228  finfo->func_name = g_strdup (st->x.str_val);
229  finfo->caller_file = g_strdup (err_fname ? err_fname : nasl_name);
230  finfo->caller_func = g_strdup (current_fun_def);
231  *def_func_tree = g_slist_prepend (*def_func_tree, finfo);
232  /* Check if function parameters are used multiple times. Only check
233  * this if we are in lint mode 1 to not check it multiple times. */
234  if (lint_mode == 1)
235  {
236  GSList *func_params = NULL;
237  int linenum = st->line_nb;
238  tree_cell *args = st->link[0];
239  for (; args != NULL; args = args->link[1])
240  {
241  if (args->x.str_val)
242  {
243  /* Check if param was already used */
244  if (!g_slist_find_custom (func_params, args->x.str_val,
245  (GCompareFunc) list_cmp))
246  func_params =
247  g_slist_prepend (func_params, args->x.str_val);
248  else
249  {
250  g_message ("%s: Error at or near line %d. "
251  "Parameter \"%s\" passed to function \"%s\" "
252  "was provided multiple times.",
253  finfo->caller_file, linenum, args->x.str_val,
254  finfo->func_name);
255  g_slist_free (func_params);
256  return NULL;
257  }
258  }
259  }
260  g_slist_free (func_params);
261  }
262  }
263 
264  switch (st->type)
265  {
266  case NODE_FUN_DEF:
267  /* with lint_mode = 0 check if this function was declared twice*/
268  if (lint_mode == 0)
269  {
270  if (decl_nasl_func (lexic, st, lint_mode) == NULL)
271  ret = NULL;
272  return ret;
273  }
274  /* Check if it was already added */
275  if (!g_slist_find_custom (*called_funcs, st->x.str_val,
276  (GCompareFunc) list_cmp))
277  {
278  return FAKE_CELL;
279  }
280 
281  /* x.str_val = function name, [0] = argdecl, [1] = block */
282  decl_nasl_func (lexic, st, lint_mode);
283  current_fun_def = g_strdup (st->x.str_val);
284  incname = g_strdup (nasl_get_filename (st->x.str_val));
285  g_hash_table_replace (*include_files, incname, g_strdup ("NO"));
286  tmp_filename = g_strdup (nasl_get_filename (NULL));
287  err_fname = g_strdup (incname);
288  /* fallthrough */
289 
290  default:
291  for (i = 0; i < 4; i++)
292  if (st->link[i] != NULL && st->link[i] != FAKE_CELL)
293  if ((ret = nasl_lint_def (lexic, st->link[i], lint_mode,
294  include_files, func_fnames_tab, err_fname,
295  called_funcs, def_func_tree))
296  == NULL)
297  return NULL;
298 
299  if (st->type == NODE_FUN_DEF)
300  {
301  if (tmp_filename)
302  nasl_set_filename (tmp_filename);
303  g_free (tmp_filename);
304  }
305  return ret;
306  }
307 }
308 
316 static char *
318 {
319  if (st == NULL)
320  return NULL;
321 
322  if (st->type != NODE_ARG)
323  return NULL;
324 
325  tree_cell *cp;
326  for (cp = st; cp != NULL; cp = cp->link[1])
327  {
328  if (!g_strcmp0 (cp->x.str_val, name))
329  return cp->link[0]->x.str_val;
330  }
331 
332  return NULL;
333 }
334 
342 static tree_cell *
344 {
345  char *name = get_argument_by_name (st, "name");
346  char *value = get_argument_by_name (st, "value");
347  char *csv = get_argument_by_name (st, "csv");
348 
349  if (((value == NULL) && (csv == NULL)) || name == NULL)
350  {
351  nasl_perror (lexic,
352  "script_xref() syntax error - should be"
353  " script_xref(name:<name>, value:<value>) or"
354  " script_xref(name:<name>, value:<value>, csv:<CSVs>) or"
355  " script_xref(name:<name>, csv:<CSVs>)\n");
356  if (name == NULL)
357  {
358  nasl_perror (lexic, " <name> is empty\n");
359  }
360  else
361  {
362  nasl_perror (lexic, " <name> is %s\n", name);
363  }
364  if ((value == NULL) && (csv == NULL))
365  {
366  nasl_perror (lexic, " <value> and <csv> is empty)\n");
367  }
368  else
369  {
370  nasl_perror (lexic, " <value> is %s\n)", value);
371  nasl_perror (lexic, " <csv> is %s\n)", csv);
372  }
373  return NULL;
374  }
375  return FAKE_CELL;
376 }
377 
385 static tree_cell *
387 {
388  lexic->line_nb = st->line_nb;
389  if (st != NULL)
390  {
391  if (!g_strcmp0 (st->x.str_val, "script_xref"))
392  return validate_script_xref (lexic, st->link[0]);
393  }
394  else
395  return NULL;
396 
397  return FAKE_CELL;
398 }
399 
404 static int
405 is_deffunc_used (const char *funcname, const char *filename,
406  GSList *def_func_tree)
407 {
408  func_info *element;
409  GSList *current = def_func_tree;
410 
411  if (current == NULL)
412  return 0;
413 
414  do
415  {
416  element = current->data;
417  if (g_strcmp0 (element->func_name, funcname) == 0
418  && g_strcmp0 (element->caller_file, filename) != 0)
419  return 1;
420  current = current->next;
421  }
422  while (current != NULL && current->next != NULL);
423  return 0;
424 }
425 
426 int features = 0;
427 
428 void
430 {
431  features = flag;
432 }
433 
437 static tree_cell *
438 nasl_lint_call (lex_ctxt *lexic, tree_cell *st, GHashTable **include_files,
439  GHashTable **func_fnames_tab, gchar *err_fname,
440  GSList **called_funcs, GSList **def_func_tree)
441 {
442  int i;
443  tree_cell *ret = FAKE_CELL;
444  nasl_func *pf;
445  char *incname = NULL;
446  int f_inc_ord, c_inc_order, rc = 0;
447  static int defined_flag = 0;
448 
452  if (st->type == NODE_FUN_DEF)
453  {
454  if (!g_slist_find_custom (*called_funcs, st->x.str_val,
455  (GCompareFunc) list_cmp))
456  {
457  return FAKE_CELL;
458  }
459  }
460 
461  switch (st->type)
462  {
463  case CONST_DATA:
464  case CONST_STR:
465  if (st->x.str_val != NULL && defined_flag == 1)
466  {
467  decl_nasl_func (lexic, st, 1);
468  defined_flag = 0;
469  }
470  return FAKE_CELL;
471 
472  case NODE_FUN_CALL:
473  pf = get_func_ref_by_name (lexic, st->x.str_val);
474 
475  if (pf == NULL)
476  {
477  incname = g_hash_table_lookup (*func_fnames_tab, st->x.str_val);
478 
479  nasl_set_filename (incname ? incname : "unknown");
480  lexic->line_nb = st->line_nb;
481 
482  GSList *called_f_aux;
483  called_f_aux = g_slist_find_custom (*def_func_tree, st->x.str_val,
484  (GCompareFunc) list_cmp1);
485  if (called_f_aux != NULL)
486  {
487  if (reverse_search (def_func_tree, called_f_aux))
488  {
489  nasl_perror (lexic, "Undefined function '%s'\n",
490  st->x.str_val);
491  return NULL;
492  }
493  }
494  }
495  else
496  {
497  // only check functions that are not internal
499  && func_is_internal (st->x.str_val) == NULL)
500  {
501  // get incname verify include order when not 0
502  incname = (char *) nasl_get_filename (st->x.str_val);
503  if (incname != NULL)
504  {
505  f_inc_ord = nasl_get_include_order (incname);
506  c_inc_order = nasl_get_include_order (st->name);
507  // if caller definition is not the main file but included
508  // before the function definition warn about an include error
509  if (c_inc_order > 0 && c_inc_order < f_inc_ord)
510  {
511  nasl_perror (
512  lexic, "%s must be included after %s (usage of %s).",
513  st->name, incname, st->x.str_val);
514  rc = -1;
515  }
516  }
517  }
518  // Check if function parameters are right
519  if (validate_function (lexic, st) == NULL)
520  return NULL;
521  }
522  if (*include_files && st->x.str_val)
523  {
524  if (g_hash_table_lookup (*include_files,
525  nasl_get_filename (st->x.str_val)))
526  {
527  incname = g_strdup (nasl_get_filename (st->x.str_val));
528  if (is_deffunc_used (st->x.str_val, incname, *def_func_tree))
529  {
530  g_hash_table_replace (*include_files, incname,
531  g_strdup ("YES"));
532  }
533  }
534  }
535  if (g_strcmp0 (st->x.str_val, "defined_func") == 0)
536  defined_flag = 1;
537  /* fallthrough */
538 
539  default:
540  for (i = 0; i < 4; i++)
541  if (st->link[i] != NULL && st->link[i] != FAKE_CELL)
542  if ((ret = nasl_lint_call (lexic, st->link[i], include_files,
543  func_fnames_tab, err_fname, called_funcs,
544  def_func_tree))
545  == NULL)
546  return NULL;
547  return rc == 0 ? ret : NULL;
548  }
549 }
550 
556 static tree_cell *
557 nasl_lint_defvar (lex_ctxt *lexic, tree_cell *st, GHashTable **include_files,
558  GHashTable **func_fnames_tab, gchar *err_fname,
559  GSList **defined_var, GSList **called_funcs)
560 {
561  int i;
562  tree_cell *ret = FAKE_CELL;
563  static int defined_fn_mode = 0;
564  static int defined_var_mode = 0;
565  static int def_glob_var = 0;
566  static GSList *local_var_list = NULL;
567 
571  if (st->type == NODE_FUN_DEF)
572  {
573  if (!g_slist_find_custom (*called_funcs, st->x.str_val,
574  (GCompareFunc) list_cmp))
575  {
576  return FAKE_CELL;
577  }
578  }
579 
580  if ((defined_fn_mode == 1 || def_glob_var) && st->type != NODE_DECL)
581  {
582  defined_fn_mode = 0;
583  def_glob_var = 0;
584  }
585 
586  /* A variable will be defined, then set the mode variable. */
587  if ((st->type == NODE_AFF || st->type == EXPR_NOT || st->type == EXPR_INCR
588  || st->type == NODE_PLUS_EQ)
589  && defined_var_mode == 0)
590  defined_var_mode = 1;
591  else if ((st->type == NODE_FUN_DEF || st->type == NODE_LOCAL
592  || st->type == NODE_FUN_CALL)
593  && defined_fn_mode == 0)
594  {
595  defined_fn_mode = 1;
596  defined_var_mode = 0;
597  }
598 
599  else if (st->type == NODE_GLOBAL)
600  def_glob_var = 1;
601 
602  /* The variable is being defined. Therefore is save into the
603  * global list only if was not previously added in local list.
604  */
605  else if ((st->type == NODE_VAR || st->type == NODE_ARRAY_EL)
606  && (defined_var_mode == 1 || defined_fn_mode == 1))
607  {
608  if (st->x.str_val != NULL)
609  {
610  if (!g_slist_find_custom (local_var_list, st->x.str_val,
611  (GCompareFunc) list_cmp))
612  *defined_var = g_slist_prepend (*defined_var, st->x.str_val);
613  defined_var_mode = 0;
614  }
615  }
619  else if (st->type == NODE_DECL && st->x.str_val != NULL)
620  {
621  if (defined_fn_mode == 1)
622  {
623  local_var_list = g_slist_prepend (local_var_list, st->x.str_val);
624  }
625  if (def_glob_var == 1)
626  {
627  *defined_var = g_slist_prepend (*defined_var, st->x.str_val);
628  }
629  }
630  /* Special case foreach. */
631  else if (st->type == NODE_FOREACH)
632  {
633  // Hacky way of checking if we are in a function definition by checking
634  // if local_var_list is non empty. Otherwise all variables declared in a
635  // foreach call are considered file scope which leads to false negatives.
636  if (st->x.str_val != NULL && local_var_list != NULL)
637  {
638  local_var_list = g_slist_prepend (local_var_list, st->x.str_val);
639  }
640  else if (st->x.str_val != NULL)
641  {
642  *defined_var = g_slist_prepend (*defined_var, st->x.str_val);
643  }
644  }
645 
646  // The variable is used. It checks if the variable was defined
647  // Also check for NODE_ARRAY_EL to catch use of undeclared array.
648  // E.g "if(foo[0]) {}" and foo was not declared previously.
649  else if ((st->type == NODE_VAR || st->type == NODE_ARRAY_EL)
650  && defined_var_mode == 0)
651  {
652  if (!g_slist_find_custom (*defined_var, st->x.str_val,
653  (GCompareFunc) list_cmp)
654  && !g_slist_find_custom (local_var_list, st->x.str_val,
655  (GCompareFunc) list_cmp))
656  {
657  lexic->line_nb = st->line_nb;
658  nasl_perror (lexic, "The variable %s was not declared",
659  st->x.str_val);
660  inc_errors_cnt ();
661  }
662  }
663 
664  for (i = 0; i < 4; i++)
665  if (st->link[i] != NULL && st->link[i] != FAKE_CELL)
666  if ((ret = nasl_lint_defvar (lexic, st->link[i], include_files,
667  func_fnames_tab, err_fname, defined_var,
668  called_funcs))
669  == NULL)
670  return NULL;
671 
675  if (st->type == NODE_FUN_DEF)
676  {
677  g_slist_free (local_var_list);
678  local_var_list = NULL;
679  }
680 
681  return ret;
682 }
686 static tree_cell *
687 make_call_func_list (lex_ctxt *lexic, tree_cell *st, GSList **called_funcs)
688 {
689  int i;
690  tree_cell *ret = FAKE_CELL;
691  nasl_func *pf = NULL;
692 
693  switch (st->type)
694  {
695  case NODE_FUN_CALL:
696  pf = get_func_ref_by_name (lexic, st->x.str_val);
697  if (st->x.str_val && !pf)
698  {
699  *called_funcs =
700  g_slist_prepend (*called_funcs, g_strdup (st->x.str_val));
701  }
702  /* fallthrough */
703 
704  default:
705  for (i = 0; i < 4; i++)
706  if (st->link[i] != NULL && st->link[i] != FAKE_CELL)
707  if ((ret = make_call_func_list (lexic, st->link[i], called_funcs))
708  == NULL)
709  return NULL;
710  return ret;
711  }
712 }
713 
717 static tree_cell *
719 {
720  int i;
721  tree_cell *ret = FAKE_CELL;
722 
723  switch (st->type)
724  {
725  case CONST_STR:
726  if (g_strrstr (st->x.str_val, ", ") != NULL)
727  {
728  g_message ("%s: An error in script_xrefs function was found. "
729  "Spaces after a comma are not allow in xrefs names "
730  "or values: '%s'",
731  nasl_get_filename (st->x.str_val), st->x.str_val);
732  return NULL;
733  }
734  /* fallthrough */
735  default:
736  for (i = 0; i < 4; i++)
737  if (st->link[i] != NULL && st->link[i] != FAKE_CELL)
738  if ((ret = check_description_block_xref (lexic, st->link[i])) == NULL)
739  return NULL;
740  }
741  return ret;
742 }
743 
748 static tree_cell *
750 {
751  int i;
752  tree_cell *ret = FAKE_CELL;
753 
754  if (st->type == NODE_FUN_CALL)
755  if (!g_strcmp0 (st->x.str_val, "script_xref"))
756  if ((ret = check_description_block_xref (lexic, st)) == NULL)
757  return NULL;
758 
759  for (i = 0; i < 4; i++)
760  if (st->link[i] != NULL && st->link[i] != FAKE_CELL)
761  if ((ret = check_description_block (lexic, st->link[i])) == NULL)
762  return NULL;
763 
764  return ret;
765 }
766 
772 static tree_cell *
774 {
775  int i;
776  tree_cell *ret = FAKE_CELL;
777  tree_cell *st_aux = NULL;
778 
779  if (st && st->type == NODE_IF_ELSE)
780  {
781  for (i = 0; i < 4; i++)
782  if (st->link[i] != NULL && st->link[i] != FAKE_CELL)
783  {
784  st_aux = st->link[i];
785  if (st_aux->type == NODE_VAR
786  && !g_strcmp0 (st_aux->x.str_val, "description"))
787  return st;
788  }
789  }
790  else
791  for (i = 0; i < 4; i++)
792  {
793  if (st->link[i] != NULL && st->link[i] != FAKE_CELL)
794  if ((ret = find_description_block (lexic, st->link[i])) == NULL)
795  return NULL;
796  return ret;
797  }
798  return NULL;
799 }
800 
810 tree_cell *
812 {
813  lex_ctxt *lexic_aux;
814  tree_cell *ret = FAKE_CELL;
815  int lint_mode = 1;
816  GHashTable *include_files = NULL;
817  GHashTable *func_fnames_tab = NULL;
818  GSList *unusedfiles = NULL;
819  GSList *called_funcs = NULL;
820  GSList *def_func_tree = NULL;
821  gchar *err_fname = NULL;
822  tree_cell *desc_block = FAKE_CELL;
823  init_errors_cnt ();
824 
825  nasl_name = g_strdup (nasl_get_filename (st->x.str_val));
826  include_files =
827  g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
828  func_fnames_tab =
829  g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
830 
831  lexic_aux = init_empty_lex_ctxt ();
832  lexic_aux->script_infos = lexic->script_infos;
833  lexic_aux->oid = lexic->oid;
834 
835  /* Check description block sanity. */
836  desc_block = find_description_block (lexic_aux, st);
837  if (desc_block != NULL && desc_block != FAKE_CELL)
838  {
839  /* FAKE_CELL if success, NULL otherwise which counts as error */
840  if (check_description_block (lexic_aux, desc_block) == NULL)
841  {
842  inc_errors_cnt ();
843  }
844  }
845  /* Make a list of all called functions */
846  make_call_func_list (lexic_aux, st, &called_funcs);
847 
848  /* Loads all defined functions. */
849  if (nasl_lint_def (lexic_aux, st, lint_mode, &include_files, &func_fnames_tab,
850  err_fname, &called_funcs, &def_func_tree)
851  == NULL)
852  {
853  inc_errors_cnt ();
854  }
855  /* Check if a called function was defined. */
856 
857  if (nasl_lint_call (lexic_aux, st, &include_files, &func_fnames_tab,
858  err_fname, &called_funcs, &def_func_tree)
859  == NULL)
860  {
861  inc_errors_cnt ();
862  }
863 
864  /* Check if the included files are used or not. */
865  g_hash_table_foreach (include_files, (GHFunc) check_called_files,
866  &unusedfiles);
867  if (unusedfiles != NULL)
868  g_slist_foreach (unusedfiles, (GFunc) print_uncall_files, lexic_aux);
869  if ((g_slist_length (unusedfiles)) > 0)
870  {
871  inc_errors_cnt ();
872  }
873 
874  /* Now check that each function was loaded just once. */
875  lint_mode = 0;
876  if (nasl_lint_def (lexic, st, lint_mode, &include_files, &func_fnames_tab,
877  err_fname, &called_funcs, &def_func_tree)
878  == NULL)
879  {
880  inc_errors_cnt ();
881  }
882 
883  /* Check if a variable was declared. */
884  GSList *defined_var = NULL;
885  add_predef_varname (&defined_var);
886  ret = nasl_lint_defvar (lexic_aux, st, &include_files, &func_fnames_tab,
887  err_fname, &defined_var, &called_funcs);
888  g_slist_free (defined_var);
889  defined_var = NULL;
890 
891  g_slist_free (called_funcs);
892  called_funcs = NULL;
893  g_slist_free_full (def_func_tree, (GDestroyNotify) free_list_func);
894  def_func_tree = NULL;
895  g_hash_table_destroy (include_files);
896  include_files = NULL;
897  g_hash_table_destroy (func_fnames_tab);
898  func_fnames_tab = NULL;
899  g_free (err_fname);
900  g_slist_free (unusedfiles);
901  unusedfiles = NULL;
902  free_lex_ctxt (lexic_aux);
903 
904  if (get_errors_cnt () > 0)
905  {
906  ret = alloc_typed_cell (NODE_VAR);
907  ret->x.i_val = get_errors_cnt ();
908  }
909 
910  return ret;
911 }
NODE_LOCAL
@ NODE_LOCAL
Definition: nasl_tree.h:32
get_func_ref_by_name
nasl_func * get_func_ref_by_name(lex_ctxt *ctxt, const char *name)
Definition: nasl_func.c:82
get_argument_by_name
static char * get_argument_by_name(tree_cell *st, char *name)
Checks if a given Arguments is within a given Argument List.
Definition: lint.c:317
CONST_DATA
@ CONST_DATA
Definition: nasl_tree.h:82
struct_lex_ctxt::line_nb
int line_nb
Definition: nasl_lex_ctxt.h:33
free_list_func
static void free_list_func(func_info *data)
Free a func_info structure.
Definition: lint.c:66
reverse_search
static gint reverse_search(GSList **def_func_tree, GSList *finfo)
Check if an undefined called function is needed or not. This is the case in which the function is cal...
Definition: lint.c:118
NODE_DECL
@ NODE_DECL
Definition: nasl_tree.h:23
TC::str_val
char * str_val
Definition: nasl_tree.h:103
NODE_GLOBAL
@ NODE_GLOBAL
Definition: nasl_tree.h:33
TC::name
char * name
Definition: nasl_tree.h:97
NODE_AFF
@ NODE_AFF
Definition: nasl_tree.h:30
CONST_STR
@ CONST_STR
Definition: nasl_tree.h:80
st_func_info::caller_func
gchar * caller_func
Definition: lint.c:35
NODE_ARRAY_EL
@ NODE_ARRAY_EL
Definition: nasl_tree.h:29
TC::x
union TC::@5 x
st_nasl_func
Definition: nasl_func.h:15
FAKE_CELL
#define FAKE_CELL
Definition: nasl_tree.h:110
st_func_info::caller_file
gchar * caller_file
Definition: lint.c:36
nasl_lint_def
static tree_cell * nasl_lint_def(lex_ctxt *lexic, tree_cell *st, int lint_mode, GHashTable **include_files, GHashTable **func_fnames_tab, gchar *err_fname, GSList **called_funcs, GSList **def_func_tree)
Loads all defined functions. Also, It constructs a tree of called functions to help recognize a not d...
Definition: lint.c:203
NODE_FUN_DEF
@ NODE_FUN_DEF
Definition: nasl_tree.h:21
make_call_func_list
static tree_cell * make_call_func_list(lex_ctxt *lexic, tree_cell *st, GSList **called_funcs)
Make a list of all called functions.
Definition: lint.c:687
exec.h
name
const char * name
Definition: nasl_init.c:411
nasl_get_include_order
int nasl_get_include_order(const char *)
Definition: nasl_grammar.tab.c:2815
add_predef_varname
static void add_predef_varname(GSList **defined_var)
Add keywords to the varnames list.
Definition: lint.c:81
validate_script_xref
static tree_cell * validate_script_xref(lex_ctxt *lexic, tree_cell *st)
Validates parameters of a script_xref function call.
Definition: lint.c:343
NODE_FUN_CALL
@ NODE_FUN_CALL
Definition: nasl_tree.h:22
nasl_debug.h
NODE_FOREACH
@ NODE_FOREACH
Definition: nasl_tree.h:18
nasl_perror
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition: nasl_debug.c:111
decl_nasl_func
tree_cell * decl_nasl_func(lex_ctxt *lexic, tree_cell *decl_node, int lint_mode)
Definition: nasl_func.c:66
init_errors_cnt
static void init_errors_cnt()
Definition: lint.c:43
NODE_VAR
@ NODE_VAR
Definition: nasl_tree.h:31
func_is_internal
nasl_func * func_is_internal(const char *)
Definition: nasl_init.c:526
print_uncall_files
static void print_uncall_files(gpointer filename, gpointer lexic)
It shows a msg for unused included files.
Definition: lint.c:186
st_func_info
Define struct to store information about a called function.
Definition: lint.c:33
nasl_lex_ctxt.h
func_info
struct st_func_info func_info
Define struct to store information about a called function.
TC::line_nb
short line_nb
Definition: nasl_tree.h:96
nasl_lint
tree_cell * nasl_lint(lex_ctxt *lexic, tree_cell *st)
Search for errors in a nasl script.
Definition: lint.c:811
get_errors_cnt
static int get_errors_cnt()
Definition: lint.c:54
EXPR_NOT
@ EXPR_NOT
Definition: nasl_tree.h:47
struct_lex_ctxt::oid
const char * oid
Definition: nasl_lex_ctxt.h:31
check_description_block_xref
static tree_cell * check_description_block_xref(lex_ctxt *lexic, tree_cell *st)
Sanity check of the script_xref parameters in the description block.
Definition: lint.c:718
free_lex_ctxt
void free_lex_ctxt(lex_ctxt *c)
Definition: nasl_lex_ctxt.c:43
nasl.h
add_nasl_library
void add_nasl_library(GSList **list)
Add "built-in" variables to a list.
Definition: nasl_init.c:554
nasl_func.h
is_deffunc_used
static int is_deffunc_used(const char *funcname, const char *filename, GSList *def_func_tree)
Returns 1 if the function is at least used once by another caller than filename otherwise 0.
Definition: lint.c:405
struct_lex_ctxt::script_infos
struct script_infos * script_infos
Definition: nasl_lex_ctxt.h:30
NLFF_STRICT_INCLUDES
@ NLFF_STRICT_INCLUDES
Definition: lint.h:16
list_cmp1
static gint list_cmp1(gconstpointer lelem, gconstpointer data)
This function is called by g_slist_find_custom.
Definition: lint.c:101
TC
Definition: nasl_tree.h:94
struct_lex_ctxt
Definition: nasl_lex_ctxt.h:23
TC::type
short type
Definition: nasl_tree.h:95
TC::link
struct TC * link[4]
Definition: nasl_tree.h:107
nasl_var.h
find_description_block
static tree_cell * find_description_block(lex_ctxt *lexic, tree_cell *st)
Sanity check of the description block.
Definition: lint.c:773
errors_cnt
int errors_cnt
Definition: lint.c:41
st_func_info::func_name
gchar * func_name
Definition: lint.c:34
nasl_global_ctxt.h
EXPR_INCR
@ EXPR_INCR
Definition: nasl_tree.h:61
NODE_IF_ELSE
@ NODE_IF_ELSE
Definition: nasl_tree.h:14
inc_errors_cnt
static void inc_errors_cnt()
Definition: lint.c:48
nasl_lint_call
static tree_cell * nasl_lint_call(lex_ctxt *lexic, tree_cell *st, GHashTable **include_files, GHashTable **func_fnames_tab, gchar *err_fname, GSList **called_funcs, GSList **def_func_tree)
Check if a called function was defined.
Definition: lint.c:438
validate_function
static tree_cell * validate_function(lex_ctxt *lexic, tree_cell *st)
Validate functions.
Definition: lint.c:386
nasl_init.h
nasl_get_filename
const char * nasl_get_filename(const char *function)
Definition: nasl_debug.c:60
nasl_set_filename
void nasl_set_filename(const char *filename)
Definition: nasl_debug.c:88
nasl_lint_feature_flags
void nasl_lint_feature_flags(int flag)
Definition: lint.c:429
features
int features
Definition: lint.c:426
NODE_PLUS_EQ
@ NODE_PLUS_EQ
Definition: nasl_tree.h:35
list_cmp
static gint list_cmp(gconstpointer lelem, gconstpointer data)
This function is called by g_slist_find_custom.
Definition: lint.c:151
alloc_typed_cell
tree_cell * alloc_typed_cell(int typ)
Definition: nasl_tree.c:28
check_called_files
static void check_called_files(gpointer key, gpointer value, GSList **unusedfiles)
This function is called by g_hash_table_foreach to check if an include file was used or not....
Definition: lint.c:169
nasl_lint_defvar
static tree_cell * nasl_lint_defvar(lex_ctxt *lexic, tree_cell *st, GHashTable **include_files, GHashTable **func_fnames_tab, gchar *err_fname, GSList **defined_var, GSList **called_funcs)
Consider all cases in which a variable is set, and add it to a list. If a variable is read,...
Definition: lint.c:557
init_empty_lex_ctxt
lex_ctxt * init_empty_lex_ctxt()
Definition: nasl_lex_ctxt.c:20
lint.h
NODE_ARG
@ NODE_ARG
Definition: nasl_tree.h:24
check_description_block
static tree_cell * check_description_block(lex_ctxt *lexic, tree_cell *st)
Sanity check of the description block.
Definition: lint.c:749
nasl_tree.h
nasl_name
char * nasl_name
Definition: lint.c:39
TC::i_val
long int i_val
Definition: nasl_tree.h:104