]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
testsuite, mi: prevent buffer overflow in get_mi_thread_list
authorTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Tue, 18 Feb 2025 08:13:43 +0000 (09:13 +0100)
committerTankut Baris Aktemur <tankut.baris.aktemur@intel.com>
Tue, 18 Feb 2025 08:13:43 +0000 (09:13 +0100)
If there is a large number of threads in the input program, the expect
buffer in `get_mi_thread_list` would become full.  Prevent this by
consuming the buffer in small pieces.

Regression-tested using the gdb.mi tests.

Approved-By: Simon Marchi <simon.marchi@efficios.com>
gdb/testsuite/lib/mi-support.exp

index c976fa11c771c9d5bcd13c3935e9495a9fc53202..206971cdb706818363fb6659fdb1a80e5b37ffee 100644 (file)
@@ -1953,39 +1953,40 @@ proc mi_run_inline_test { testcase } {
 }
 
 proc get_mi_thread_list {name} {
-    global expect_out
-
     # MI will return a list of thread ids:
     #
     # -thread-list-ids
-    # ^done,thread-ids=[thread-id="1",thread-id="2",...],number-of-threads="N"
+    # ^done,thread-ids={thread-id="1",thread-id="2",...},number-of-threads="N"
     # (gdb)
-    mi_gdb_test "-thread-list-ids" \
-       {.*\^done,thread-ids={(thread-id="[0-9]+"(,)?)+},current-thread-id="[0-9]+",number-of-threads="[0-9]+"} \
-       "-thread_list_ids ($name)"
-
-    set output {}
-    if {[info exists expect_out(buffer)]} {
-       set output $expect_out(buffer)
-    }
-
+    #
+    # In case there are too many threads, the expect buffer would
+    # become full.  Process the buffer contents in small chunks.
     set thread_list {}
-    if {![regexp {thread-ids=\{(thread-id="[0-9]+"(,)?)*\}} $output threads]} {
-       fail "finding threads in MI output ($name)"
-    } else {
-       pass "finding threads in MI output ($name)"
-
-       # Make list of console threads
-       set start [expr {[string first \{ $threads] + 1}]
-       set end   [expr {[string first \} $threads] - 1}]
-       set threads [string range $threads $start $end]
-       foreach thread [split $threads ,] {
-           if {[scan $thread {thread-id="%d"} num]} {
-               lappend thread_list $num
-           }
+    set num_threads "unknown"
+    set test "$name: get MI thread list"
+    gdb_test_multiple "-thread-list-ids" $test -prompt "$::mi_gdb_prompt" {
+       -re "done,thread-ids=\{" {
+           exp_continue
+       }
+       -re "^thread-id=\"($::decimal)\"(,|\})" {
+           lappend thread_list $expect_out(1,string)
+           exp_continue
+       }
+       -re "^,current-thread-id=\"$::decimal\"" {
+           exp_continue
+       }
+       -re "^,number-of-threads=\"($::decimal)\"" {
+           set num_threads $expect_out(1,string)
+           exp_continue
+       }
+       -re "^\r\n$::mi_gdb_prompt" {
+           pass $gdb_test_name
        }
     }
 
+    gdb_assert {[llength $thread_list] == $num_threads} \
+       "$name: found thread ids in MI output"
+
     return $thread_list
 }