This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[RFA] Fix regexp problem with "operator* etc.


The following operations --

	info func operator*
	info func operator*=
	info func operator->*
	info func operator[]
	info func operator char*

will cause gdb to do something other than was (probably) intended, 
because the argument to the info function command is a regular
expression, and the "*" and "[]" bits will be interpreted by the 
regular expression parser.

This patch will allow the user to quote these function names eg.

	info func operator\*
	info func operator\*=
	info func operator->\*
	info func operator\[\]
	info func operator char\*

and thereby avoid having to treat them as special cases against
the regular expression language.

I also caught a case where alloca was being used to allocate a
buffer that was too small, thereby running the risk of corrupting
the stack.

A patch to the testsuite is included, which eliminates five fails.
2001-11-01  Michael Snyder  <msnyder@redhat.com>

	* symtab.c (operator_chars): Allow '*' and '[' to be quoted in
	operator names, to avoid regexp expansion.
	(search_symbols): Alloca buffer is too small, may get clobbered.

	* gdb.c++/cplusfuncs.exp: Fix conflicts between operator names
	and regular expression operators by using quoting.

Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.46
diff -c -3 -p -r1.46 symtab.c
*** symtab.c	2001/10/17 07:12:57	1.46
--- symtab.c	2001/11/02 02:08:54
*************** operator_chars (char *p, char **end)
*** 2067,2119 ****
        return p;
      }
  
!   switch (*p)
!     {
!     case '!':
!     case '=':
!     case '*':
!     case '/':
!     case '%':
!     case '^':
!       if (p[1] == '=')
! 	*end = p + 2;
!       else
  	*end = p + 1;
!       return p;
!     case '<':
!     case '>':
!     case '+':
!     case '-':
!     case '&':
!     case '|':
!       if (p[1] == '=' || p[1] == p[0])
  	*end = p + 2;
!       else
! 	*end = p + 1;
!       return p;
!     case '~':
!     case ',':
!       *end = p + 1;
!       return p;
!     case '(':
!       if (p[1] != ')')
! 	error ("`operator ()' must be specified without whitespace in `()'");
!       *end = p + 2;
!       return p;
!     case '?':
!       if (p[1] != ':')
! 	error ("`operator ?:' must be specified without whitespace in `?:'");
!       *end = p + 2;
!       return p;
!     case '[':
!       if (p[1] != ']')
! 	error ("`operator []' must be specified without whitespace in `[]'");
!       *end = p + 2;
!       return p;
!     default:
!       error ("`operator %s' not supported", p);
!       break;
!     }
    *end = "";
    return *end;
  }
--- 2067,2168 ----
        return p;
      }
  
!   while (*p)
!     switch (*p)
!       {
!       case '\\':			/* regexp quoting */
! 	if (p[1] == '*')
! 	  {
! 	    if (p[2] == '=')	/* 'operator\*=' */
! 	      *end = p + 3;
! 	    else			/* 'operator\*'  */
! 	      *end = p + 2;
! 	    return p;
! 	  }
! 	else if (p[1] == '[')
! 	  {
! 	    if (p[2] == ']')
! 	      error ("mismatched quoting on brackets, try 'operator\\[\\]'");
! 	    else if (p[2] == '\\' && p[3] == ']')
! 	      {
! 		*end = p + 4;	/* 'operator\[\]' */
! 		return p;
! 	      }
! 	    else
! 	      error ("nothing is allowed between '[' and ']'");
! 	  }
! 	else 
! 	  {
! 	    /* Gratuitous qoute: skip it and move on. */
! 	    p++;
! 	    continue;
! 	  }
! 	break;
!       case '!':
!       case '=':
!       case '*':
!       case '/':
!       case '%':
!       case '^':
! 	if (p[1] == '=')
! 	  *end = p + 2;
! 	else
! 	  *end = p + 1;
! 	return p;
!       case '<':
!       case '>':
!       case '+':
!       case '-':
!       case '&':
!       case '|':
! 	if (p[0] == '-' && p[1] == '>')
! 	  {
! 	    /* Struct pointer member operator 'operator->'. */
! 	    if (p[2] == '*')
! 	      {
! 		*end = p + 3;	/* 'operator->*' */
! 		return p;
! 	      }
! 	    else if (p[2] == '\\')
! 	      {
! 		*end = p + 4;	/* Hopefully 'operator->\*' */
! 		return p;
! 	      }
! 	    else
! 	      {
! 		*end = p + 2;	/* 'operator->' */
! 		return p;
! 	      }
! 	  }
! 	if (p[1] == '=' || p[1] == p[0])
! 	  *end = p + 2;
! 	else
! 	  *end = p + 1;
! 	return p;
!       case '~':
!       case ',':
  	*end = p + 1;
! 	return p;
!       case '(':
! 	if (p[1] != ')')
! 	  error ("`operator ()' must be specified without whitespace in `()'");
  	*end = p + 2;
! 	return p;
!       case '?':
! 	if (p[1] != ':')
! 	  error ("`operator ?:' must be specified without whitespace in `?:'");
! 	*end = p + 2;
! 	return p;
!       case '[':
! 	if (p[1] != ']')
! 	  error ("`operator []' must be specified without whitespace in `[]'");
! 	*end = p + 2;
! 	return p;
!       default:
! 	error ("`operator %s' not supported", p);
! 	break;
!       }
! 
    *end = "";
    return *end;
  }
*************** search_symbols (char *regexp, namespace_
*** 2365,2371 ****
  	  /* If wrong number of spaces, fix it. */
  	  if (fix >= 0)
  	    {
! 	      char *tmp = (char *) alloca (opend - opname + 10);
  	      sprintf (tmp, "operator%.*s%s", fix, " ", opname);
  	      regexp = tmp;
  	    }
--- 2414,2420 ----
  	  /* If wrong number of spaces, fix it. */
  	  if (fix >= 0)
  	    {
! 	      char *tmp = (char *) alloca (strlen (regexp) + fix);
  	      sprintf (tmp, "operator%.*s%s", fix, " ", opname);
  	      regexp = tmp;
  	    }
Index: testsuite/gdb.c++/cplusfuncs.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/cplusfuncs.exp,v
retrieving revision 1.2
diff -c -3 -p -r1.2 cplusfuncs.exp
*** cplusfuncs.exp	2001/02/14 19:54:04	1.2
--- cplusfuncs.exp	2001/11/02 02:08:54
*************** if  { [gdb_compile "${srcdir}/${subdir}/
*** 60,65 ****
--- 60,66 ----
  
  set dm_operator_comma		","
  set dm_type_char_star		"char*"
+ set dm_type_char_star_quoted    "char\\*"
  set dm_type_foo_ref 		"foo&"
  set dm_type_int_star		"int*"
  set dm_type_long_star		"long*"
*************** proc probe_demangler { } {
*** 71,76 ****
--- 72,78 ----
      global gdb_prompt
      global dm_operator_comma
      global dm_type_char_star
+     global dm_type_char_star_quoted
      global dm_type_foo_ref
      global dm_type_int_star
      global dm_type_long_star
*************** proc probe_demangler { } {
*** 102,107 ****
--- 104,110 ----
  	-re ".*dm_type_char_star\\(char \\*\\).*\r\n$gdb_prompt $" {
  	    # v2 demangler
  	    set dm_type_char_star "char *"
+ 	    set dm_type_char_star_quoted "char \\*"
  	    pass "detect dm_type_char_star"
  	}
  	-re ".*dm_type_char_star\\(char\\*\\).*\r\n$gdb_prompt $" {
*************** proc print_addr { name } {
*** 312,317 ****
--- 315,321 ----
  proc test_lookup_operator_functions {} {
      global dm_operator_comma
      global dm_type_char_star
+     global dm_type_char_star_quoted
      global dm_type_foo_ref
      global dm_type_void
      global dm_type_void_star
*************** proc test_lookup_operator_functions {} {
*** 323,329 ****
  	return
      }
  
!     info_func "operator*("	"void foo::operator*($dm_type_foo_ref);"
      info_func "operator%("	"void foo::operator%($dm_type_foo_ref);"
      info_func "operator-("	"void foo::operator-($dm_type_foo_ref);"
      info_func "operator>>("	"void foo::operator>>($dm_type_foo_ref);"
--- 327,334 ----
  	return
      }
  
!     # operator* requires quoting so that GDB does not treat it as a regexp.
!     info_func "operator\\*("	"void foo::operator*($dm_type_foo_ref);"
      info_func "operator%("	"void foo::operator%($dm_type_foo_ref);"
      info_func "operator-("	"void foo::operator-($dm_type_foo_ref);"
      info_func "operator>>("	"void foo::operator>>($dm_type_foo_ref);"
*************** proc test_lookup_operator_functions {} {
*** 336,342 ****
      info_func "operator++("	"void foo::operator++(int);"
      info_func "operator=("	"void foo::operator=($dm_type_foo_ref);"
      info_func "operator+=("	"void foo::operator+=($dm_type_foo_ref);"
!     info_func "operator*=("	"void foo::operator*=($dm_type_foo_ref);"
      info_func "operator%=("	"void foo::operator%=($dm_type_foo_ref);"
      info_func "operator>>=("	"void foo::operator>>=($dm_type_foo_ref);"
      info_func "operator|=("	"void foo::operator|=($dm_type_foo_ref);"
--- 341,348 ----
      info_func "operator++("	"void foo::operator++(int);"
      info_func "operator=("	"void foo::operator=($dm_type_foo_ref);"
      info_func "operator+=("	"void foo::operator+=($dm_type_foo_ref);"
!     # operator*= requires quoting so that GDB does not treat it as a regexp.
!     info_func "operator\\*=("	"void foo::operator*=($dm_type_foo_ref);"
      info_func "operator%=("	"void foo::operator%=($dm_type_foo_ref);"
      info_func "operator>>=("	"void foo::operator>>=($dm_type_foo_ref);"
      info_func "operator|=("	"void foo::operator|=($dm_type_foo_ref);"
*************** proc test_lookup_operator_functions {} {
*** 359,368 ****
      info_func "operator<<=("	"void foo::operator<<=($dm_type_foo_ref);"
      info_func "operator&=("	"void foo::operator&=($dm_type_foo_ref);"
      info_func "operator^=("	"void foo::operator^=($dm_type_foo_ref);"
!     info_func "operator->*("	"void foo::operator->*($dm_type_foo_ref);"
  
!     # operator[] needs backslashes to protect against TCL evaluation.
!     info_func "operator\[\]("	"void foo::operator\[\]($dm_type_foo_ref);"
  
      # These are gnarly because they might end with 'static'.
      set dm_type_void_star_regexp [string_to_regexp $dm_type_void_star]
--- 365,377 ----
      info_func "operator<<=("	"void foo::operator<<=($dm_type_foo_ref);"
      info_func "operator&=("	"void foo::operator&=($dm_type_foo_ref);"
      info_func "operator^=("	"void foo::operator^=($dm_type_foo_ref);"
!     # operator->* requires quoting so that GDB does not treat it as a regexp.
!     info_func "operator->\\*("	"void foo::operator->*($dm_type_foo_ref);"
  
!     # operator[] needs double backslashes, so that a single backslash
!     # will be sent to GDB, preventing the square brackets from being
!     # evaluated as a regular expression. 
!     info_func "operator\\\[\\\](" "void foo::operator\[\]($dm_type_foo_ref);"
  
      # These are gnarly because they might end with 'static'.
      set dm_type_void_star_regexp [string_to_regexp $dm_type_void_star]
*************** proc test_lookup_operator_functions {} {
*** 371,377 ****
  
      info_func "operator int("	"int foo::operator int($dm_type_void);"
      info_func "operator()("	"void foo::operator()($dm_type_foo_ref);"
!     info_func "operator $dm_type_char_star\(" \
  				"char *foo::operator $dm_type_char_star\($dm_type_void);"
  
  }
--- 380,386 ----
  
      info_func "operator int("	"int foo::operator int($dm_type_void);"
      info_func "operator()("	"void foo::operator()($dm_type_foo_ref);"
!     info_func "operator $dm_type_char_star_quoted\(" \
  				"char *foo::operator $dm_type_char_star\($dm_type_void);"
  
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]