Fix memory leak (OSS-Fuzz issue #32246)

Signed-off-by: Stefan Weil <sw@weilnetz.de>
This commit is contained in:
Stefan Weil 2021-04-10 10:59:52 +02:00
parent f2c6378b5a
commit f77b1c6881
10 changed files with 54 additions and 50 deletions

View File

@ -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

View File

@ -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_;
}

View File

@ -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.

View File

@ -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());
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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();

View File

@ -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;