diff options
Diffstat (limited to 'apps/buffering.c')
-rw-r--r-- | apps/buffering.c | 38 |
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; |