summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/buffering.c38
1 files changed, 17 insertions, 21 deletions
diff --git a/apps/buffering.c b/apps/buffering.c
index 1482d6790b..14db47bb91 100644
--- a/apps/buffering.c
+++ b/apps/buffering.c
@@ -666,31 +666,25 @@ static bool buffer_handle(int handle_id)
666 while (h->filerem > 0 && !stop) 666 while (h->filerem > 0 && !stop)
667 { 667 {
668 /* max amount to copy */ 668 /* max amount to copy */
669 size_t copy_n = MIN( MIN(h->filerem, BUFFERING_DEFAULT_FILECHUNK), 669 ssize_t copy_n = MIN( MIN(h->filerem, BUFFERING_DEFAULT_FILECHUNK),
670 buffer_len - h->widx); 670 buffer_len - h->widx);
671 uintptr_t offset = h->next ? ringbuf_offset(h->next) : buf_ridx;
672 ssize_t overlap = ringbuf_add_cross(h->widx, copy_n, offset);
671 673
672 ssize_t overlap; 674 if (!h->next)
673 uintptr_t next_handle = ringbuf_offset(h->next); 675 overlap++; /* sub one more below to avoid buffer overflow */
674 676
675 /* stop copying if it would overwrite the reading position */ 677 if (overlap > 0)
676 if (ringbuf_add_cross(h->widx, copy_n, buf_ridx) >= 0)
677 return false;
678
679 /* FIXME: This would overwrite the next handle
680 * If this is true, then there's a handle even though we have still
681 * data to buffer. This should NEVER EVER happen! (but it does :( ) */
682 if (h->next && (overlap
683 = ringbuf_add_cross(h->widx, copy_n, next_handle)) > 0)
684 { 678 {
685 /* stop buffering data for now and post-pone buffering the rest */ 679 /* read only up to available space and stop if it would overwrite
680 the reading position or the next handle */
686 stop = true; 681 stop = true;
687 DEBUGF( "%s(): Preventing handle corruption: h1.id:%d h2.id:%d"
688 " copy_n:%lu overlap:%ld h1.filerem:%lu\n", __func__,
689 h->id, h->next->id, (unsigned long)copy_n, (long)overlap,
690 (unsigned long)h->filerem);
691 copy_n -= overlap; 682 copy_n -= overlap;
692 } 683 }
693 684
685 if (copy_n <= 0)
686 return false; /* no space for read */
687
694 /* rc is the actual amount read */ 688 /* rc is the actual amount read */
695 int rc = read(h->fd, &buffer[h->widx], copy_n); 689 int rc = read(h->fd, &buffer[h->widx], copy_n);
696 690
@@ -830,12 +824,14 @@ static void shrink_handle(struct memory_handle *h)
830 if (!h) 824 if (!h)
831 return; 825 return;
832 826
833 if (h->next && h->filerem == 0 && 827 if (h->type == TYPE_ID3 || h->type == TYPE_CUESHEET ||
834 (h->type == TYPE_ID3 || h->type == TYPE_CUESHEET || 828 h->type == TYPE_BITMAP || h->type == TYPE_CODEC ||
835 h->type == TYPE_BITMAP || h->type == TYPE_CODEC || 829 h->type == TYPE_ATOMIC_AUDIO)
836 h->type == TYPE_ATOMIC_AUDIO))
837 { 830 {
838 /* metadata handle: we can move all of it */ 831 /* metadata handle: we can move all of it */
832 if (!h->next || h->filerem != 0)
833 return; /* Last handle or not finished loading */
834
839 uintptr_t handle_distance = 835 uintptr_t handle_distance =
840 ringbuf_sub(ringbuf_offset(h->next), h->data); 836 ringbuf_sub(ringbuf_offset(h->next), h->data);
841 delta = handle_distance - h->available; 837 delta = handle_distance - h->available;