mirror of
https://github.com/tesseract-ocr/tesseract.git
synced 2025-06-12 05:13:14 +08:00
Fix memory leak (OSS-Fuzz issue #32246)
Signed-off-by: Stefan Weil <sw@weilnetz.de>
This commit is contained in:
parent
f2c6378b5a
commit
f77b1c6881
@ -378,7 +378,7 @@ void BLOBNBOX::DeleteNoiseBlobs(BLOBNBOX_LIST *blobs) {
|
||||
for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
|
||||
BLOBNBOX *blob = blob_it.data();
|
||||
if (blob->DeletableNoise()) {
|
||||
delete blob->cblob();
|
||||
delete blob->remove_cblob();
|
||||
delete blob_it.extract();
|
||||
}
|
||||
}
|
||||
@ -926,16 +926,6 @@ TO_BLOCK::TO_BLOCK( // make a block
|
||||
block = src_block;
|
||||
}
|
||||
|
||||
static void clear_blobnboxes(BLOBNBOX_LIST *boxes) {
|
||||
BLOBNBOX_IT it = boxes;
|
||||
// A BLOBNBOX generally doesn't own its blobs, so if they do, you
|
||||
// have to delete them explicitly.
|
||||
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
|
||||
BLOBNBOX *box = it.data();
|
||||
delete box->cblob();
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
* TO_BLOCK::clear
|
||||
*
|
||||
@ -963,11 +953,11 @@ void TO_BLOCK::clear() {
|
||||
|
||||
TO_BLOCK::~TO_BLOCK() {
|
||||
// Any residual BLOBNBOXes at this stage own their blobs, so delete them.
|
||||
clear_blobnboxes(&blobs);
|
||||
clear_blobnboxes(&underlines);
|
||||
clear_blobnboxes(&noise_blobs);
|
||||
clear_blobnboxes(&small_blobs);
|
||||
clear_blobnboxes(&large_blobs);
|
||||
BLOBNBOX::clear_blobnboxes(&blobs);
|
||||
BLOBNBOX::clear_blobnboxes(&underlines);
|
||||
BLOBNBOX::clear_blobnboxes(&noise_blobs);
|
||||
BLOBNBOX::clear_blobnboxes(&small_blobs);
|
||||
BLOBNBOX::clear_blobnboxes(&large_blobs);
|
||||
}
|
||||
|
||||
// Helper function to divide the input blobs over noise, small, medium
|
||||
|
@ -154,6 +154,18 @@ public:
|
||||
delete cblob_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
static void clear_blobnboxes(BLOBNBOX_LIST *boxes) {
|
||||
BLOBNBOX_IT it = boxes;
|
||||
// A BLOBNBOX generally doesn't own its blobs, so if they do, you
|
||||
// have to delete them explicitly.
|
||||
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
|
||||
BLOBNBOX *box = it.data();
|
||||
// TODO: remove next line, currently still needed for resultiterator_test.
|
||||
delete box->remove_cblob();
|
||||
}
|
||||
}
|
||||
|
||||
static BLOBNBOX *RealBlob(C_OUTLINE *outline) {
|
||||
auto *blob = new C_BLOB(outline);
|
||||
return new BLOBNBOX(blob);
|
||||
@ -265,6 +277,12 @@ public:
|
||||
C_BLOB *cblob() const {
|
||||
return cblob_ptr;
|
||||
}
|
||||
C_BLOB *remove_cblob() {
|
||||
auto blob = cblob_ptr;
|
||||
cblob_ptr = nullptr;
|
||||
owns_cblob_ = false;
|
||||
return blob;
|
||||
}
|
||||
TabType left_tab_type() const {
|
||||
return left_tab_type_;
|
||||
}
|
||||
|
@ -360,14 +360,9 @@ WERD &WERD::operator=(const WERD &source) {
|
||||
flags = source.flags;
|
||||
script_id_ = source.script_id_;
|
||||
correct = source.correct;
|
||||
if (!cblobs.empty()) {
|
||||
cblobs.clear();
|
||||
}
|
||||
cblobs.clear();
|
||||
cblobs.deep_copy(&source.cblobs, &C_BLOB::deep_copy);
|
||||
|
||||
if (!rej_cblobs.empty()) {
|
||||
rej_cblobs.clear();
|
||||
}
|
||||
rej_cblobs.clear();
|
||||
rej_cblobs.deep_copy(&source.rej_cblobs, &C_BLOB::deep_copy);
|
||||
return *this;
|
||||
}
|
||||
@ -537,7 +532,7 @@ bool WERD::AddSelectedOutlines(const std::vector<bool> &wanted,
|
||||
*make_next_word_fuzzy = false;
|
||||
}
|
||||
C_BLOB_IT rej_it(&rej_cblobs);
|
||||
for (int i = 0; i < outlines.size(); ++i) {
|
||||
for (unsigned i = 0; i < outlines.size(); ++i) {
|
||||
C_OUTLINE *outline = outlines[i];
|
||||
if (outline == nullptr) {
|
||||
continue; // Already used it.
|
||||
|
@ -275,12 +275,11 @@ void CCNonTextDetect::MarkAndDeleteNonTextBlobs(BLOBNBOX_LIST *blobs, int max_bl
|
||||
blob->plot(win, ScrollView::RED, ScrollView::RED);
|
||||
}
|
||||
#endif // !GRAPHICS_DISABLED
|
||||
// It is safe to delete the cblob now, as it isn't used by the grid
|
||||
// or BlobOverlapsTooMuch, and the BLOBNBOXes will go away with the
|
||||
// dead_blobs list.
|
||||
// TODO(rays) delete the delete when the BLOBNBOX destructor deletes
|
||||
// the cblob.
|
||||
delete blob->cblob();
|
||||
// It is safe to delete the cblob now, as it isn't used by the grid
|
||||
// or BlobOverlapsTooMuch, and the BLOBNBOXes will go away with the
|
||||
// dead_blobs list.
|
||||
// TODO: remove next line, currently still needed for resultiterator_test.
|
||||
delete blob->remove_cblob();
|
||||
dead_it.add_to_end(blob_it.extract());
|
||||
}
|
||||
}
|
||||
|
@ -322,7 +322,8 @@ void ColPartition::DeleteBoxes() {
|
||||
// and the BLOBNBOXes own the underlying C_BLOBs.
|
||||
for (BLOBNBOX_C_IT bb_it(&boxes_); !bb_it.empty(); bb_it.forward()) {
|
||||
BLOBNBOX *bblob = bb_it.extract();
|
||||
delete bblob->cblob();
|
||||
// TODO: remove next line, currently still needed for resultiterator_test.
|
||||
delete bblob->remove_cblob();
|
||||
delete bblob;
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +267,7 @@ void split_to_blob( // split the blob
|
||||
C_BLOB *real_cblob; // cblob to chop
|
||||
|
||||
if (blob != nullptr) {
|
||||
real_cblob = blob->cblob();
|
||||
real_cblob = blob->remove_cblob();
|
||||
} else {
|
||||
real_cblob = nullptr;
|
||||
}
|
||||
|
@ -181,6 +181,7 @@ void assign_blobs_to_blocks2(Image pix,
|
||||
for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
|
||||
blob = blob_it.extract();
|
||||
newblob = new BLOBNBOX(blob); // Convert blob to BLOBNBOX.
|
||||
newblob->set_owns_cblob(true);
|
||||
SetBlobStrokeWidth(pix, newblob);
|
||||
port_box_it.add_after_then_move(newblob);
|
||||
}
|
||||
|
@ -864,8 +864,6 @@ the gap between the word being built and the next one. */
|
||||
float repetition_spacing; // gap between repetitions
|
||||
int32_t xstarts[2]; // row ends
|
||||
int32_t prev_x; // end of prev blob
|
||||
BLOBNBOX *bblob; // current blob
|
||||
TBOX blob_box; // bounding box
|
||||
BLOBNBOX_IT box_it; // iterator
|
||||
TBOX prev_blob_box;
|
||||
TBOX next_blob_box;
|
||||
@ -935,18 +933,21 @@ the gap between the word being built and the next one. */
|
||||
|
||||
peek_at_next_gap(row, box_it, next_blob_box, next_gap, next_within_xht_gap);
|
||||
do {
|
||||
bblob = box_it.data();
|
||||
blob_box = bblob->bounding_box();
|
||||
auto bblob = box_it.data();
|
||||
auto blob_box = bblob->bounding_box();
|
||||
if (bblob->joined_to_prev()) {
|
||||
if (bblob->cblob() != nullptr) {
|
||||
auto cblob = bblob->remove_cblob();
|
||||
if (cblob != nullptr) {
|
||||
cout_it.set_to_list(cblob_it.data()->out_list());
|
||||
cout_it.move_to_last();
|
||||
cout_it.add_list_after(bblob->cblob()->out_list());
|
||||
delete bblob->cblob();
|
||||
cout_it.add_list_after(cblob->out_list());
|
||||
delete cblob;
|
||||
}
|
||||
} else {
|
||||
if (bblob->cblob() != nullptr) {
|
||||
cblob_it.add_after_then_move(bblob->cblob());
|
||||
auto cblob = bblob->cblob();
|
||||
if (cblob != nullptr) {
|
||||
bblob->set_owns_cblob(false);
|
||||
cblob_it.add_after_then_move(cblob);
|
||||
}
|
||||
prev_x = blob_box.right();
|
||||
}
|
||||
|
@ -84,10 +84,7 @@ void restore_underlined_blobs( // get chop points
|
||||
ru_it.add_after_then_move(new BLOBNBOX(new C_BLOB(&left_coutlines)));
|
||||
}
|
||||
}
|
||||
if (u_line != nullptr) {
|
||||
delete u_line->cblob();
|
||||
delete u_line;
|
||||
}
|
||||
delete u_line;
|
||||
}
|
||||
if (!ru_it.empty()) {
|
||||
ru_it.move_to_first();
|
||||
|
@ -62,15 +62,17 @@ void make_single_word(bool one_blob, TO_ROW_LIST *rows, ROW_LIST *real_rows) {
|
||||
for (; !box_it.empty(); box_it.forward()) {
|
||||
BLOBNBOX *bblob = box_it.extract();
|
||||
if (bblob->joined_to_prev() || (one_blob && !cblob_it.empty())) {
|
||||
if (bblob->cblob() != nullptr) {
|
||||
auto cblob = bblob->remove_cblob();
|
||||
if (cblob != nullptr) {
|
||||
C_OUTLINE_IT cout_it(cblob_it.data()->out_list());
|
||||
cout_it.move_to_last();
|
||||
cout_it.add_list_after(bblob->cblob()->out_list());
|
||||
delete bblob->cblob();
|
||||
cout_it.add_list_after(cblob->out_list());
|
||||
delete cblob;
|
||||
}
|
||||
} else {
|
||||
if (bblob->cblob() != nullptr) {
|
||||
cblob_it.add_after_then_move(bblob->cblob());
|
||||
auto cblob = bblob->remove_cblob();
|
||||
if (cblob != nullptr) {
|
||||
cblob_it.add_after_then_move(cblob);
|
||||
}
|
||||
}
|
||||
delete bblob;
|
||||
|
Loading…
Reference in New Issue
Block a user