diff options
author | wm4 <nfxjfg@googlemail.com> | 2014-03-25 13:53:11 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-03-26 18:27:25 +0100 |
commit | 5b0ce5d4e3660fb0fc86779cbd027b47b1758c9f (patch) | |
tree | 0a0a2202937ae60d6cba348d1c4ba1894f2d3abd /libavfilter | |
parent | 54e2e9fbc15e7c652576d12b01512dbe9010cdf8 (diff) | |
download | ffmpeg-5b0ce5d4e3660fb0fc86779cbd027b47b1758c9f.tar.gz |
vf_pullup: simplify, fix double free error
The memory allocation for f->diffs was freed multiple times in some
corner cases. Simplify the code so that this doesn't happen.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavfilter')
-rw-r--r-- | libavfilter/vf_pullup.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/libavfilter/vf_pullup.c b/libavfilter/vf_pullup.c index 58d4d7a1ea..bf8456814f 100644 --- a/libavfilter/vf_pullup.c +++ b/libavfilter/vf_pullup.c @@ -126,20 +126,20 @@ static int alloc_metrics(PullupContext *s, PullupField *f) return 0; } -static void free_field_queue(PullupField *head, PullupField **last) +static void free_field_queue(PullupField *head) { PullupField *f = head; - while (f) { + do { + PullupField *next; + if (!f) + break; av_free(f->diffs); av_free(f->combs); av_free(f->vars); - if (f == *last) { - av_freep(last); - break; - } - f = f->next; - av_freep(&f->prev); - }; + next = f->next; + av_free(f); + f = next; + } while (f != head); } static PullupField *make_field_queue(PullupContext *s, int len) @@ -158,14 +158,14 @@ static PullupField *make_field_queue(PullupContext *s, int len) for (; len > 0; len--) { f->next = av_mallocz(sizeof(*f->next)); if (!f->next) { - free_field_queue(head, &f); + free_field_queue(head); return NULL; } f->next->prev = f; f = f->next; if (alloc_metrics(s, f) < 0) { - free_field_queue(head, &f); + free_field_queue(head); return NULL; } } @@ -736,7 +736,8 @@ static av_cold void uninit(AVFilterContext *ctx) PullupContext *s = ctx->priv; int i; - free_field_queue(s->head, &s->last); + free_field_queue(s->head); + s->last = NULL; for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) { av_freep(&s->buffers[i].planes[0]); |