2009-09-21 Phil Muldoon <pmuldoon@redhat.com>
authorPhil Muldoon <pmuldoon@redhat.com>
Mon, 21 Sep 2009 09:32:28 +0000 (09:32 +0000)
committerPhil Muldoon <pmuldoon@redhat.com>
Mon, 21 Sep 2009 09:32:28 +0000 (09:32 +0000)
* python/py-value.c (valpy_getitem): Test value before allowing
subscript operation.

2009-09-21  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.
(ptr_ref): New function.

gdb/ChangeLog
gdb/python/py-value.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-value.c
gdb/testsuite/gdb.python/py-value.exp

index d81f43a2a47c523080f72d05faa712df771dd5fb..54cae78c62183cc8b4b7608bd8a934b80f64c7b4 100644 (file)
@@ -1,3 +1,8 @@
+2009-09-21  Phil Muldoon <pmuldoon@redhat.com>
+
+       * python/py-value.c (valpy_getitem): Test value before allowing
+       subscript operation.
+
 2009-09-21  Hui Zhu  <teawater@gmail.com>
            Michael Snyder  <msnyder@vmware.com>
 
index 3d88aa31f8b2ab24afdcd6791b9a944ff1ad626f..714aa1180055c8b5d324e9a8c6fa17c5eb77ae13 100644 (file)
@@ -324,7 +324,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));
+           }
        }
     }
 
index d4b706e4801f9ab3b0a538b1523836d722efe574..defe02c8f9cbdbeefeb9c15a0862901797befed6 100644 (file)
@@ -1,3 +1,10 @@
+2009-09-21  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.
+       (ptr_ref): New function.
+
 2009-09-17  Paul Pluzhnikov  <ppluzhnikov@google.com>
 
        * gdb.base/default.exp: Fix "show convenience".
index f3d62845369ea0a534d8792ec0ec17638c0ccf18..023d830796b9018a52749c5271fc1885b06927b2 100644 (file)
@@ -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 */
 }
index 9b4190de19a1a5a805461eccda64dec13e95dc52..29582339961ced3b87038d6f3981dc51856c435c 100644 (file)
@@ -292,6 +292,75 @@ proc test_value_after_death {} {
     "print value's type"
 }
 
+# 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
@@ -322,3 +391,8 @@ if ![runto_main] then {
 
 test_value_in_inferior
 test_value_after_death
+
+# The following test recompiles the binary to test either C or C++
+# values. 
+test_subscript_regression "c++"
+test_subscript_regression "c"