Branch: Tag:

2008-05-17

2008-05-17 22:48:33 by Henrik Grubbström (Grubba) <grubba@grubba.org>

First go at format string checking for sscanf et al.
Added __handle_sscanf_format().
F_SSCANF-nodes are now type checked with new_check_call() (just like ordinary function calls).
new_check_call() now accepts and detects F_LVALUE_LIST nodes as arguments.
Added flag CALL_ARG_LVALUE to indicate that checked arguments are lvalues.

Rev: src/builtin_functions.c:1.664
Rev: src/las.c:1.410
Rev: src/pike_types.c:1.335
Rev: src/pike_types.h:1.117
Rev: src/sscanf.c:1.179
Rev: src/sscanf.h:1.5

2:   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: las.c,v 1.409 2008/05/17 14:09:28 marcus Exp $ + || $Id: las.c,v 1.410 2008/05/17 22:48:32 grubba Exp $   */      #include "global.h"
3232:    return name;   }    - struct pike_type *new_check_call(struct pike_string *fun_name, -  struct pike_type *fun_type, -  node *args, int *argno); -  +    void fix_type_field(node *n)   {    struct compilation *c = THIS_COMPILATION;
3532: Inside #if defined(NEW_ARG_CHECK)
      /* NOTE: new_check_call() steals a reference from f! */    copy_pike_type(f, CAR(n)->type); -  f = debug_malloc_pass(new_check_call(name, f, CDR(n), &args)); +  f = debug_malloc_pass(new_check_call(name, f, CDR(n), &args, 0));       if (!f) {    /* Errors have been generated. */
4107:    !CDAR(n) || (CDAR(n)->token != F_ARG_LIST) ||    !CADAR(n) || !CDDAR(n)) {    yyerror("Too few arguments to sscanf()."); +  MAKE_CONSTANT_TYPE(n->type, tIntPos);    } else { -  check_node_type(CADAR(n), string_type_string, -  "Bad argument 1 to sscanf()."); -  check_node_type(CDDAR(n), string_type_string, -  "Bad argument 2 to sscanf()."); +  struct pike_string *sscanf_name; +  struct pike_type *sscanf_type; +  node *args; +  INT32 argno = 0; +  if (CAAR(n)->u.sval.u.integer & SSCANF_FLAG_76_COMPAT) { +  MAKE_CONST_STRING(sscanf_name, "sscanf_76"); +  add_ref(sscanf_type = sscanf_76_type_string); +  } else { +  MAKE_CONST_STRING(sscanf_name, "sscanf"); +  add_ref(sscanf_type = sscanf_type_string);    } -  /* FIXME: */ +  args = mknode(F_ARG_LIST, CDAR(n), CDR(n)); +  add_ref(CDAR(n)); +  add_ref(CDR(n)); +  sscanf_type = new_check_call(sscanf_name, sscanf_type, args, &argno, 0); +  free_node(args); +  if (sscanf_type) { +  n->type = new_get_return_type(sscanf_type, 0); +  free_type(sscanf_type); +  } else {    MAKE_CONSTANT_TYPE(n->type, tIntPos); -  +  } +  }    break;       case F_UNDEFINED: