Commit 5ca34b6b for tesseract
commit 5ca34b6b386ae09c8a6571b750fdac116cccbe40
Author: Stefan Weil <sw@weilnetz.de>
Date: Sat Aug 15 16:41:24 2026 +0200
Fix CID 1685284 (Resource leak)
The rows of a paragraph run all reference the same PARA object, whose
ownership was transferred from a unique_ptr to the row_owners vector
via an intermediate raw pointer. Coverity could not track that the
pointer was stored by the loop and reported a leak.
Transfer ownership directly to the first row of the run with release(),
then let the remaining rows reference the same paragraph by copying the
pointer from the vector.
Also fix a typo in the function name in the tprintf message.
Assisted-by: OpenCode / Qwen3.8-27B-Thinking (Alibaba Cloud)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
diff --git a/src/ccmain/paragraphs.cpp b/src/ccmain/paragraphs.cpp
index 15b9fde2..e04c2336 100644
--- a/src/ccmain/paragraphs.cpp
+++ b/src/ccmain/paragraphs.cpp
@@ -2148,15 +2148,20 @@ static void ConvertHypothesizedModelRunsToParagraphs(std::vector<RowScratchRegis
p->is_list_item = model->justification() == JUSTIFICATION_RIGHT
? rows[start].ri_->rword_indicates_list_item
: rows[start].ri_->lword_indicates_list_item;
- PARA *para = p.release();
+ // Free any stale owners of the rows of the run, then give all rows of
+ // the run a reference to the new paragraph, whose ownership is
+ // transferred directly to the first row of the run.
for (int row = start; row < end; row++) {
if ((*row_owners)[row] != nullptr) {
tprintf(
- "Memory leak! ConvertHypothesizeModelRunsToParagraphs() called "
+ "Memory leak! ConvertHypothesizedModelRunsToParagraphs() called "
"more than once!\n");
delete (*row_owners)[row];
}
- (*row_owners)[row] = para;
+ }
+ (*row_owners)[start] = p.release();
+ for (int row = start + 1; row < end; row++) {
+ (*row_owners)[row] = (*row_owners)[start];
}
}
}