# HG changeset patch # User Mikael Berthe # Date 1194819215 -3600 # Node ID ff1f6facdc0c6cd70c23c91eb9e797dffd762962 # Parent 32077249de773aec21e632a5e2050ab36ff265c5 Allow dynamic HBB sizes diff -r 32077249de77 -r ff1f6facdc0c mcabber/src/hbuf.c --- a/mcabber/src/hbuf.c Sun Nov 11 18:49:43 2007 +0100 +++ b/mcabber/src/hbuf.c Sun Nov 11 23:13:35 2007 +0100 @@ -123,18 +123,26 @@ { GList *curr_elt; char *line; + guint hbb_blocksize, textlen; hbuf_block *hbuf_block_elt; if (!text) return; + textlen = strlen(text); + hbb_blocksize = MAX(textlen+1, HBB_BLOCKSIZE); + hbuf_block_elt = g_new0(hbuf_block, 1); hbuf_block_elt->prefix.timestamp = timestamp; hbuf_block_elt->prefix.flags = prefix_flags; hbuf_block_elt->prefix.mucnicklen = mucnicklen; if (!*p_hbuf) { - hbuf_block_elt->ptr = g_new(char, HBB_BLOCKSIZE); + hbuf_block_elt->ptr = g_new(char, hbb_blocksize); + if (!hbuf_block_elt->ptr) { + g_free(hbuf_block_elt); + return; + } hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT; - hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE; + hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + hbb_blocksize; } else { hbuf_block *hbuf_b_prev; // Set p_hbuf to the end of the list, to speed up history loading @@ -147,17 +155,15 @@ } *p_hbuf = g_list_append(*p_hbuf, hbuf_block_elt); - if (strlen(text) >= HBB_BLOCKSIZE) { - // Too long - text = "[ERR:LINE_TOO_LONG]"; - hbuf_block_elt->prefix.flags |= HBB_PREFIX_INFO; - } - - if (hbuf_block_elt->ptr + strlen(text) >= hbuf_block_elt->ptr_end_alloc) { + if (hbuf_block_elt->ptr + textlen >= hbuf_block_elt->ptr_end_alloc) { // Too long for the current allocated bloc, we need another one - if (!maxhbufblocks) { + if (!maxhbufblocks || textlen >= HBB_BLOCKSIZE) { // No limit, let's allocate a new block - hbuf_block_elt->ptr = g_new0(char, HBB_BLOCKSIZE); + // If the message text is big, we won't bother to reuse an old block + // as well (it could be too small and cause a segfault). + hbuf_block_elt->ptr = g_new0(char, hbb_blocksize); + hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + hbb_blocksize; + // XXX We should check the return value. } else { GList *hbuf_head, *hbuf_elt; hbuf_block *hbuf_b_elt; @@ -174,10 +180,12 @@ } // If we can't allocate a new area, reuse the previous block(s) if (n < maxhbufblocks) { - hbuf_block_elt->ptr = g_new0(char, HBB_BLOCKSIZE); + hbuf_block_elt->ptr = g_new0(char, hbb_blocksize); + hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + hbb_blocksize; } else { // Let's use an old block, and free the extra blocks if needed char *allocated_block = NULL; + char *end_of_allocated_block = NULL; while (n >= maxhbufblocks) { int start_of_block = 1; for (hbuf_elt = hbuf_head; hbuf_elt; hbuf_elt = hbuf_head) { @@ -185,28 +193,30 @@ if (hbuf_b_elt->flags & HBB_FLAG_ALLOC) { if (start_of_block-- == 0) break; - if (n == maxhbufblocks) + if (n == maxhbufblocks) { allocated_block = hbuf_b_elt->ptr; - else + end_of_allocated_block = hbuf_b_elt->ptr_end_alloc; + } else { g_free(hbuf_b_elt->ptr); + } } g_free(hbuf_b_elt); hbuf_head = *p_hbuf = g_list_delete_link(hbuf_head, hbuf_elt); } n--; } - memset(allocated_block, 0, HBB_BLOCKSIZE); + memset(allocated_block, 0, end_of_allocated_block-allocated_block); hbuf_block_elt->ptr = allocated_block; + hbuf_block_elt->ptr_end_alloc = end_of_allocated_block; } } hbuf_block_elt->flags = HBB_FLAG_ALLOC | HBB_FLAG_PERSISTENT; - hbuf_block_elt->ptr_end_alloc = hbuf_block_elt->ptr + HBB_BLOCKSIZE; } line = hbuf_block_elt->ptr; // Ok, now we can copy the text.. strcpy(line, text); - hbuf_block_elt->ptr_end = line + strlen(line) + 1; + hbuf_block_elt->ptr_end = line + textlen + 1; curr_elt = g_list_last(*p_hbuf);