Skip to content

Commit

Permalink
Destroy MIMEFieldBlockImpl that doesn't have fields in use
Browse files Browse the repository at this point in the history
Because MIMEFieldBlocks are destroyed only when MIMEHdr is destroyed, the block
chain never be short. With this change, a block will be destroyed when all fields
in a block are deleted, and the block will be removed from a block chain.

(cherry picked from commit 482e30a)
  • Loading branch information
maskit authored and zwoop committed Oct 21, 2019
1 parent e0d70d6 commit 08ed061
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
40 changes: 27 additions & 13 deletions proxy/hdrs/MIME.cc
Expand Up @@ -1639,20 +1639,8 @@ mime_hdr_field_delete(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, bool del
{
if (delete_all_dups) {
while (field) {
// NOTE: we pass zero to field_detach for detach_all_dups
// since this loop will already detach each dup
MIMEField *next = field->m_next_dup;

heap->free_string(field->m_ptr_name, field->m_len_name);
heap->free_string(field->m_ptr_value, field->m_len_value);

MIME_HDR_SANITY_CHECK(mh);
mime_hdr_field_detach(mh, field, false);

MIME_HDR_SANITY_CHECK(mh);
mime_field_destroy(mh, field);

MIME_HDR_SANITY_CHECK(mh);
mime_hdr_field_delete(heap, mh, field, false);
field = next;
}
} else {
Expand All @@ -1664,6 +1652,32 @@ mime_hdr_field_delete(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, bool del

MIME_HDR_SANITY_CHECK(mh);
mime_field_destroy(mh, field);

MIMEFieldBlockImpl *prev_block = nullptr;
bool can_destroy_block = true;
for (auto fblock = &(mh->m_first_fblock); fblock != nullptr; fblock = fblock->m_next) {
if (prev_block != nullptr) {
if (fblock->m_freetop == MIME_FIELD_BLOCK_SLOTS && fblock->contains(field)) {
// Check if fields in all slots are deleted
for (int i = 0; i < MIME_FIELD_BLOCK_SLOTS; ++i) {
if (fblock->m_field_slots[i].m_readiness != MIME_FIELD_SLOT_READINESS_DELETED) {
can_destroy_block = false;
break;
}
}
// Destroy a block and maintain the chain
if (can_destroy_block) {
prev_block->m_next = fblock->m_next;
_mime_field_block_destroy(heap, fblock);
if (prev_block->m_next == nullptr) {
mh->m_fblock_list_tail = prev_block;
}
}
break;
}
}
prev_block = fblock;
}
}

MIME_HDR_SANITY_CHECK(mh);
Expand Down
3 changes: 3 additions & 0 deletions proxy/hdrs/MIME.h
Expand Up @@ -718,6 +718,9 @@ void mime_hdr_field_attach(MIMEHdrImpl *mh, MIMEField *field, int check_for_dups
void mime_hdr_field_detach(MIMEHdrImpl *mh, MIMEField *field, bool detach_all_dups = false);
void mime_hdr_field_delete(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, bool delete_all_dups = false);

/**
* Returned slotnum is not a persistent value. A slotnum may refer a different field after making changes to a mime header.
*/
int mime_hdr_field_slotnum(MIMEHdrImpl *mh, MIMEField *field);
inkcoreapi MIMEField *mime_hdr_prepare_for_value_set(HdrHeap *heap, MIMEHdrImpl *mh, const char *name, int name_length);

Expand Down

0 comments on commit 08ed061

Please sign in to comment.