From 2e4d963fb27e10835c44564788b9c3d25bc21119 Mon Sep 17 00:00:00 2001 From: Phil Muldoon Date: Mon, 21 Sep 2009 09:32:28 +0000 Subject: [PATCH] 2009-09-21 Phil Muldoon * python/py-value.c (valpy_getitem): Test value before allowing subscript operation. 2009-09-21 Phil Muldoon * 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 | 5 +++ gdb/python/py-value.c | 13 +++++- gdb/testsuite/ChangeLog | 7 ++++ gdb/testsuite/gdb.python/py-value.c | 15 +++++++ gdb/testsuite/gdb.python/py-value.exp | 74 +++++++++++++++++++++++++++++++++++ 5 files changed, 113 insertions(+), 1 deletion(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d81f43a..54cae78 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2009-09-21 Phil Muldoon + + * python/py-value.c (valpy_getitem): Test value before allowing + subscript operation. + 2009-09-21 Hui Zhu Michael Snyder diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c index 3d88aa3..714aa11 100644 --- a/gdb/python/py-value.c +++ b/gdb/python/py-value.c @@ -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)); + } } } diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index d4b706e..defe02c 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2009-09-21 Phil Muldoon + + * 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 * gdb.base/default.exp: Fix "show convenience". 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 9b4190d..2958233 100644 --- a/gdb/testsuite/gdb.python/py-value.exp +++ b/gdb/testsuite/gdb.python/py-value.exp @@ -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" -- 2.7.4