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