Tcl Source Code

View Ticket
Login
Ticket UUID: 3595762
Title: Extra Tcl_DecrRefCount in Tcl_LSearchjObjCmd
Type: Bug Created on: 2012-12-14 03:10:43
Submitter: apnadkarni Assigned to: dkf
Subsystem: 17. Commands I-L Severity:
Priority: 4 Last modified: 2026-10-11 11:20:44
Status: Open Closed by:
Resolution: None Closed on:
Version: 8.6.18, 9.0.5, 9.1.0
Description:
There is a Tcl_DecrRefCount (patObj) (~line 3425 of TclCmdIL.c) which does not seem to have a matching Tcl_IncrRefCount. patObj is not newly allocated, it is equated to objv[...] on line 3197.

I don't know how to exercise that code, because I don't think the enclosing Tcl_RegExpExecObj call enclosing it can actually fail, the regexp having been already successfully compiled before without errors further up in the code. So in that sense it might be dead code but still...

/Ashok
User Comments:
dkf added on 2012-12-17 20:31:46:
I've reviewed the code, and the only problem cases are when the RE engine core throws REG_ASSERT or REG_ESPACE. The first is a "Yow! RE engine bug found!" and the second is running out of memory for what is typically a modest memory allocation (i.e., highly fatal to Tcl which exercises the memory subsystem pretty hard). The glue layer connecting Tcl to the RE engine ensures that other error cases don't happen (we match our RE compilations and executions correctly) or are caught earlier.

In other words, I don't think it is possible to actually exercise this bug.

serhiy.storchaka added on 2026-10-11 11:20:44:

This is reachable: matching fails with "out of memory" when the dissector's per-character work array cannot be allocated, e.g. for a quantified group with a backref on a long string. The extra Tcl_DecrRefCount(patObj) then frees the pattern while it is still in use. Reproducer: run (ulimit -v 1100000; tclsh lsearch-uaf.tcl) with

proc t {} {
    set l [list [string repeat a 100000000]]
    set pat [string cat {^(?:(a)\1)*} {$}]
    for {set i 0} {$i < 4} {incr i} {
	catch {lsearch -regexp $l $pat} msg
	puts "$msg: $pat"
    }
}
t
On 9.0.5 the last line prints invokeStk1 instead of the pattern. Proposed fix in branch lsearch-regexp-error-refcount.