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>
(cherry picked from commit 5b0ce5d4e3660fb0fc86779cbd027b47b1758c9f)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
... | ... |
@@ -126,20 +126,20 @@ static int alloc_metrics(PullupContext *s, PullupField *f) |
126 | 126 |
return 0; |
127 | 127 |
} |
128 | 128 |
|
129 |
-static void free_field_queue(PullupField *head, PullupField **last) |
|
129 |
+static void free_field_queue(PullupField *head) |
|
130 | 130 |
{ |
131 | 131 |
PullupField *f = head; |
132 |
- while (f) { |
|
132 |
+ do { |
|
133 |
+ PullupField *next; |
|
134 |
+ if (!f) |
|
135 |
+ break; |
|
133 | 136 |
av_free(f->diffs); |
134 | 137 |
av_free(f->combs); |
135 | 138 |
av_free(f->vars); |
136 |
- if (f == *last) { |
|
137 |
- av_freep(last); |
|
138 |
- break; |
|
139 |
- } |
|
140 |
- f = f->next; |
|
141 |
- av_freep(&f->prev); |
|
142 |
- }; |
|
139 |
+ next = f->next; |
|
140 |
+ av_free(f); |
|
141 |
+ f = next; |
|
142 |
+ } while (f != head); |
|
143 | 143 |
} |
144 | 144 |
|
145 | 145 |
static PullupField *make_field_queue(PullupContext *s, int len) |
... | ... |
@@ -158,14 +158,14 @@ static PullupField *make_field_queue(PullupContext *s, int len) |
158 | 158 |
for (; len > 0; len--) { |
159 | 159 |
f->next = av_mallocz(sizeof(*f->next)); |
160 | 160 |
if (!f->next) { |
161 |
- free_field_queue(head, &f); |
|
161 |
+ free_field_queue(head); |
|
162 | 162 |
return NULL; |
163 | 163 |
} |
164 | 164 |
|
165 | 165 |
f->next->prev = f; |
166 | 166 |
f = f->next; |
167 | 167 |
if (alloc_metrics(s, f) < 0) { |
168 |
- free_field_queue(head, &f); |
|
168 |
+ free_field_queue(head); |
|
169 | 169 |
return NULL; |
170 | 170 |
} |
171 | 171 |
} |
... | ... |
@@ -736,7 +736,8 @@ static av_cold void uninit(AVFilterContext *ctx) |
736 | 736 |
PullupContext *s = ctx->priv; |
737 | 737 |
int i; |
738 | 738 |
|
739 |
- free_field_queue(s->head, &s->last); |
|
739 |
+ free_field_queue(s->head); |
|
740 |
+ s->last = NULL; |
|
740 | 741 |
|
741 | 742 |
for (i = 0; i < FF_ARRAY_ELEMS(s->buffers); i++) { |
742 | 743 |
av_freep(&s->buffers[i].planes[0]); |