Index: apps/buffering.c =================================================================== --- apps/buffering.c (revision 23091) +++ apps/buffering.c (working copy) @@ -426,22 +426,28 @@ newpos = RINGBUF_ADD((void *)src - (void *)buffer, final_delta); overlap = RINGBUF_ADD_CROSS(newpos, size_to_move, buffer_len - 1); +/* The unpatched version has else if (!canwrap) instruction, +a handle with !canwrap can be wrapped because of the if ((unsigned)overlap > +datasize) instruction before. This happens rarely for the ID3 handle */ + + if (overlap > 0) { /* Some part of the struct + data would wrap, maybe ok */ size_t correction = 0; - /* If the overlap lands inside the memory_handle */ - if ((unsigned)overlap > data_size) { - /* Correct the position and real delta to prevent the struct from - * wrapping, this guarantees an aligned delta, I think */ - correction = overlap - data_size; - } else if (!can_wrap) { - /* Otherwise the overlap falls in the data area and must all be + if (!can_wrap) { + /* The overlap falls in the data or struct area and must all be * backed out. This may become conditional if ever we move * data that is allowed to wrap (ie audio) */ correction = overlap; + } + else if ((unsigned)overlap > data_size) { + /* If the overlap lands inside the memory_handle */ + /* Correct the position and real delta to prevent the struct from + * wrapping, this guarantees an aligned delta, I think */ + correction = overlap - sizeof(struct memory_handle); + } /* Align correction to four bytes, up */ correction = (correction+3) & ~3; - } if (correction) { if (final_delta < correction + sizeof(struct memory_handle)) { /* Delta cannot end up less than the size of the struct */ @@ -484,11 +490,16 @@ if (src == cur_handle) cur_handle = dest; +/* Does this take into account moving a handle which is already +wrapped ? Therefore the CODEC handle has a !canwrap status in the +patch */ + + if (overlap > 0) { size_t first_part = size_to_move - overlap; + memmove(buffer, (const char *)src + first_part, overlap); memmove(dest, src, first_part); - memmove(buffer, (const char *)src + first_part, overlap); - } else { + } else { memmove(dest, src, size_to_move); } @@ -776,7 +787,11 @@ delta = handle_distance - h->available; /* The value of delta might change for alignment reasons */ - if (!move_handle(&h, &delta, h->available, h->type==TYPE_CODEC)) + if (!move_handle(&h, &delta, h->available, false)) + +/* h->type==TYPE_CODEC changed to false. CODEC handle gets the attribute +the status !canwrap (ID3 handle is also !canwrap) */ + return; size_t olddata = h->data; @@ -938,8 +953,11 @@ return ERR_FILE_ERROR; size_t size = filesize(fd); - bool can_wrap = type==TYPE_PACKET_AUDIO || type==TYPE_CODEC; + bool can_wrap = type==TYPE_PACKET_AUDIO ; +/* if Memory is small the CODEC handle can wrap, but move_handle cannot +manage a wrapped handle */ + size_t adjusted_offset = offset; if (adjusted_offset > size) adjusted_offset = 0;