public inbox for archer@sourceware.org
 help / color / mirror / Atom feed
* [patch] Do not allow invalid subscript operations on GDB values
@ 2009-09-15  9:58 Phil Muldoon
  2009-09-15 20:43 ` Tom Tromey
  0 siblings, 1 reply; 4+ messages in thread
From: Phil Muldoon @ 2009-09-15  9:58 UTC (permalink / raw)
  To: Project Archer

[-- Attachment #1: Type: text/plain, Size: 783 bytes --]

This patches attempts to fix the discussion regarding invalid subscripts 
referenced here:

http://permalink.gmane.org/gmane.comp.gdb.devel/26807

This patch checks the value type before allowing a subscript operation 
to proceed. It also adds some regressions and general tests for value 
subscripts.

This patch was tested on x86-64, and causes no regressions.

OK?

Regards

Phil


ChangeLog

2009-09-15  Phil Muldoon <pmuldoon@redhat.com>

     * py-value.c (valpy_getitem): Test value before allowing subscript
     operation.

Testsuite ChangeLog

2009-09-15  Phil Muldoon <pmuldoon@redhat.com>

     * gdb.python/py-value.exp (test_subscript_regression): New
     function.  Test for invalid subscripts.
     * gdb.python/py-value.c (main): Add test array, and pointer to it.

[-- Attachment #2: py_subscript.patch --]
[-- Type: text/plain, Size: 3574 bytes --]

diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 159c118..d5b6753 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -328,7 +328,16 @@ valpy_getitem (PyObject *self, PyObject *key)
 	     type.  */
 	  struct value *idx = convert_value_from_python (key);
 	  if (idx != NULL)
-	    res_val = value_subscript (tmp, value_as_long (idx));
+	    {
+	      /* Check the value's type is something that can be accessed via
+		 a subscript.  */
+	      struct type *type = check_typedef (value_type (tmp));
+	      if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+		  && TYPE_CODE (type) != TYPE_CODE_PTR)
+		  error( _("Cannot subscript requested type"));
+	      else
+		res_val = value_subscript (tmp, value_as_long (idx));
+	    }
 	}
     }
 
diff --git a/gdb/testsuite/gdb.python/py-value.c b/gdb/testsuite/gdb.python/py-value.c
index f3d6284..2142ce6 100644
--- a/gdb/testsuite/gdb.python/py-value.c
+++ b/gdb/testsuite/gdb.python/py-value.c
@@ -46,6 +46,8 @@ main (int argc, char *argv[])
   PTR x = &s;
   char st[17] = "divide et impera";
   char nullst[17] = "divide\0et\0impera";
+  int a[3] = {1,2,3};
+  int *p = a;
 
   s.a = 3;
   s.b = 5;
diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
index 93cddc7..e34dfb8 100644
--- a/gdb/testsuite/gdb.python/py-value.exp
+++ b/gdb/testsuite/gdb.python/py-value.exp
@@ -301,6 +301,42 @@ proc test_cast_regression {} {
   gdb_test "python print v" "5" "print value for cast test"
 }
 
+# Regression test for invalid subscript operations.  The bug was that
+# the type of the value was not being checked before allowing a
+# subscript operation to proceed.
+proc test_subscript_regression {} {
+ gdb_py_test_silent_cmd "python intv = gdb.Value(1)" \
+     "Create a value for subscript test" 1
+ gdb_py_test_silent_cmd "python stringv = gdb.Value(\"foo\")" \
+     "Create a value for subscript test" 1
+
+ # Try to access an int with a subscript.  This should fail.
+ gdb_test "python print intv" "1" "Baseline print of a Python value"
+ gdb_test "python print intv\[0\]" "RuntimeError: Cannot subscript requested type.*" \
+     "Attempt to access an integer with a subscript"
+
+ # Try to access a string with a subscript.  This should pass.
+ gdb_test "python print stringv" "foo." "Baseline print of a Python value"
+ gdb_test "python print stringv\[0\]" "f." "Attempt to access a string with a subscript"
+
+ # Try to access an int array via a pointer with a subscript.  This should pass.
+ gdb_py_test_silent_cmd "print p" "Build pointer to array" 1
+ gdb_py_test_silent_cmd "python pointer = gdb.history(0)" "" 1
+ gdb_test "python print pointer\[0\]" "1" "Access array via pointer with int subscript"
+ gdb_test "python print pointer\[intv\]" "2" "Access array via pointer with value subscript"
+
+ # Try to access a single dimension array with a subscript to the
+ # result.  This should fail.
+ gdb_test "python print pointer\[intv\]\[0\]" "RuntimeError: Cannot subscript requested type.*" \
+     "Attempt to access an integer with a subscript"   
+
+ # Lastly, test subscript access to an array with multiple
+ # dimensions.  This should pass.
+ gdb_py_test_silent_cmd "print {\"fu \",\"foo\",\"bar\"}" "Build array" 1
+ gdb_py_test_silent_cmd "python marray = gdb.history(0)" "" 1
+ gdb_test "python print marray\[1\]\[2\]" "o." "Test multiple subscript"
+}   
+
 # Start with a fresh gdb.
 
 gdb_exit
@@ -337,5 +373,6 @@ if ![runto_main] then {
 }
 
 test_value_in_inferior
+test_subscript_regression
 test_value_after_death
 test_cast_regression

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch] Do not allow invalid subscript operations on GDB values
  2009-09-15  9:58 [patch] Do not allow invalid subscript operations on GDB values Phil Muldoon
@ 2009-09-15 20:43 ` Tom Tromey
  2009-09-16 12:43   ` Phil Muldoon
  0 siblings, 1 reply; 4+ messages in thread
From: Tom Tromey @ 2009-09-15 20:43 UTC (permalink / raw)
  To: Phil Muldoon; +Cc: Project Archer

>>>>> "Phil" == Phil Muldoon <pmuldoon@redhat.com> writes:

Phil> +	      /* Check the value's type is something that can be accessed via
Phil> +		 a subscript.  */
Phil> +	      struct type *type = check_typedef (value_type (tmp));

I see eval.c also uses coerce_ref here.
So, I wonder if this works properly with a value of type
reference-to-array or reference-to-pointer.
Could you try that?

If that fails, please add the call and commit it.

If it works, it is ok as-is, so please commit it.

Also, please submit the final patch upstream.

thanks,
Tom

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch] Do not allow invalid subscript operations on GDB values
  2009-09-15 20:43 ` Tom Tromey
@ 2009-09-16 12:43   ` Phil Muldoon
  2009-09-16 16:48     ` Tom Tromey
  0 siblings, 1 reply; 4+ messages in thread
From: Phil Muldoon @ 2009-09-16 12:43 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Project Archer

[-- Attachment #1: Type: text/plain, Size: 692 bytes --]

On 09/15/2009 09:43 PM, Tom Tromey wrote:
> If that fails, please add the call and commit it.
> If it works, it is ok as-is, so please commit it.
>
> Also, please submit the final patch upstream.
>
>    

Tom,

Thanks for looking at the patch. In an additional test I added, the 
reference fails without coerce_ref. So ... I added the coerce_ref back 
into the code. The only way I could think to test this is to add C++ 
bits to the testcase. But I'm not totally sure that I am testing your 
original concern. So before I commit, can you give it one more once 
over? The patch is pretty much the same other than the coerce_ref call, 
and the addition of the C++ test. Thanks!

Regards

Phil

[-- Attachment #2: py_subscript_a2.patch --]
[-- Type: text/plain, Size: 5141 bytes --]

diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 159c118..14efd79 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -328,7 +328,18 @@ valpy_getitem (PyObject *self, PyObject *key)
 	     type.  */
 	  struct value *idx = convert_value_from_python (key);
 	  if (idx != NULL)
-	    res_val = value_subscript (tmp, value_as_long (idx));
+	    {
+	      /* Check the value's type is something that can be accessed via
+		 a subscript.  */
+	      struct type *type;
+	      tmp = coerce_ref (tmp);
+	      type = check_typedef (value_type (tmp));
+	      if (TYPE_CODE (type) != TYPE_CODE_ARRAY
+		  && TYPE_CODE (type) != TYPE_CODE_PTR)
+		  error( _("Cannot subscript requested type"));
+	      else
+		res_val = value_subscript (tmp, value_as_long (idx));
+	    }
 	}
     }
 
diff --git a/gdb/testsuite/gdb.python/py-value.c b/gdb/testsuite/gdb.python/py-value.c
index f3d6284..023d830 100644
--- a/gdb/testsuite/gdb.python/py-value.c
+++ b/gdb/testsuite/gdb.python/py-value.c
@@ -37,6 +37,13 @@ typedef struct s *PTR;
 
 enum e evalue = TWO;
 
+#ifdef __cplusplus
+void ptr_ref(int*& rptr_int)
+{
+  return; /* break to inspect pointer by reference. */
+}
+#endif
+
 int
 main (int argc, char *argv[])
 {
@@ -46,10 +53,18 @@ main (int argc, char *argv[])
   PTR x = &s;
   char st[17] = "divide et impera";
   char nullst[17] = "divide\0et\0impera";
+  int a[3] = {1,2,3};
+  int *p = a;
+  int i = 2;
+  int *ptr_i = &i;
 
   s.a = 3;
   s.b = 5;
   u.a = 7;
 
+#ifdef __cplusplus
+  ptr_ref(ptr_i);
+#endif
+
   return 0;      /* break to inspect struct and union */
 }
diff --git a/gdb/testsuite/gdb.python/py-value.exp b/gdb/testsuite/gdb.python/py-value.exp
index 93cddc7..b9f2c3c 100644
--- a/gdb/testsuite/gdb.python/py-value.exp
+++ b/gdb/testsuite/gdb.python/py-value.exp
@@ -301,6 +301,75 @@ proc test_cast_regression {} {
   gdb_test "python print v" "5" "print value for cast test"
 }
 
+# Regression test for invalid subscript operations.  The bug was that
+# the type of the value was not being checked before allowing a
+# subscript operation to proceed.
+
+proc test_subscript_regression {lang} {
+
+ global srcdir subdir srcfile binfile testfile hex
+ if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable "debug $lang"] != "" } {
+     untested "Couldn't compile ${srcfile} in $lang mode"
+     return -1
+ }
+
+ # Start with a fresh gdb.
+ gdb_exit
+ gdb_start
+ gdb_reinitialize_dir $srcdir/$subdir
+ gdb_load ${binfile}
+
+ if ![runto_main ] then {
+     perror "couldn't run to breakpoint"
+     return
+ }
+
+ if {$lang == "c++"} {
+     gdb_breakpoint [gdb_get_line_number "break to inspect pointer by reference"]
+     gdb_continue_to_breakpoint "break to inspect pointer by reference"
+
+     gdb_py_test_silent_cmd "print rptr_int" \
+	 "Obtain address" 1
+     gdb_py_test_silent_cmd "python rptr = gdb.history(0)" \
+	 "Obtains value from GDB" 1
+     gdb_test "python print rptr\[0\]" "2" "Check pointer passed as reference"
+ }
+
+ gdb_breakpoint [gdb_get_line_number "break to inspect struct and union"]
+ gdb_continue_to_breakpoint "break to inspect struct and union"
+
+ gdb_py_test_silent_cmd "python intv = gdb.Value(1)" \
+     "Create a value for subscript test" 1
+ gdb_py_test_silent_cmd "python stringv = gdb.Value(\"foo\")" \
+     "Create a value for subscript test" 1
+
+ # Try to access an int with a subscript.  This should fail.
+ gdb_test "python print intv" "1" "Baseline print of a Python value"
+ gdb_test "python print intv\[0\]" "RuntimeError: Cannot subscript requested type.*" \
+     "Attempt to access an integer with a subscript"
+
+ # Try to access a string with a subscript.  This should pass.
+ gdb_test "python print stringv" "foo." "Baseline print of a Python value"
+ gdb_test "python print stringv\[0\]" "f." "Attempt to access a string with a subscript"
+
+ # Try to access an int array via a pointer with a subscript.  This should pass.
+ gdb_py_test_silent_cmd "print p" "Build pointer to array" 1
+ gdb_py_test_silent_cmd "python pointer = gdb.history(0)" "" 1
+ gdb_test "python print pointer\[0\]" "1" "Access array via pointer with int subscript"
+ gdb_test "python print pointer\[intv\]" "2" "Access array via pointer with value subscript"
+
+ # Try to access a single dimension array with a subscript to the
+ # result.  This should fail.
+ gdb_test "python print pointer\[intv\]\[0\]" "RuntimeError: Cannot subscript requested type.*" \
+     "Attempt to access an integer with a subscript"   
+
+ # Lastly, test subscript access to an array with multiple
+ # dimensions.  This should pass.
+ gdb_py_test_silent_cmd "print {\"fu \",\"foo\",\"bar\"}" "Build array" 1
+ gdb_py_test_silent_cmd "python marray = gdb.history(0)" "" 1
+ gdb_test "python print marray\[1\]\[2\]" "o." "Test multiple subscript"
+}   
+
 # Start with a fresh gdb.
 
 gdb_exit
@@ -339,3 +408,9 @@ if ![runto_main] then {
 test_value_in_inferior
 test_value_after_death
 test_cast_regression
+
+# The following test recompiles the binary to test either C or C++
+# values.
+
+test_subscript_regression "c++"
+test_subscript_regression "c"

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch] Do not allow invalid subscript operations on GDB values
  2009-09-16 12:43   ` Phil Muldoon
@ 2009-09-16 16:48     ` Tom Tromey
  0 siblings, 0 replies; 4+ messages in thread
From: Tom Tromey @ 2009-09-16 16:48 UTC (permalink / raw)
  To: Phil Muldoon; +Cc: Project Archer

>>>>> "Phil" == Phil Muldoon <pmuldoon@redhat.com> writes:

Phil> Thanks for looking at the patch. In an additional test I added, the
Phil> reference fails without coerce_ref. So ... I added the coerce_ref back
Phil> into the code. The only way I could think to test this is to add C++
Phil> bits to the testcase. But I'm not totally sure that I am testing your
Phil> original concern. So before I commit, can you give it one more once
Phil> over? The patch is pretty much the same other than the coerce_ref
Phil> call, and the addition of the C++ test. Thanks!

Looks good, thanks!

Tom

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2009-09-16 16:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-09-15  9:58 [patch] Do not allow invalid subscript operations on GDB values Phil Muldoon
2009-09-15 20:43 ` Tom Tromey
2009-09-16 12:43   ` Phil Muldoon
2009-09-16 16:48     ` Tom Tromey

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).