History

avformat/webpenc: Fix memleak when using invalid packets

The WebP muxer sometimes caches a packet it receives to write it later; yet if a cached packet is too small (so small as to be invalid), it is cached, but not written and not unreferenced. Such a packet leaks, either by being overwritten by the next packet or because it is never unreferenced at all. Fix this by not caching unusable packets at all; and error out on invalid packets.

Andreas Rheinhardt committed 5 years ago

Commit f9043de1 parent 484a3221 file · +11 −10Browse files

Unified · Split

libavformat/webpenc.c+11−10
@@ -53,24 +53,22 @@ static int webp_init(AVFormatContext *s) · 52 unmodified lines
53 53
54static int is_animated_webp_packet(AVPacket *pkt)54static int is_animated_webp_packet(AVPacket *pkt)
55{55{
56 if (pkt->size) {
57 int skip = 0;56 int skip = 0;
58 unsigned flags = 0;57 unsigned flags = 0;
59 58
60 if (pkt->size < 4)59 if (pkt->size < 4)
61 return 0;60 return AVERROR_INVALIDDATA;
62 if (AV_RL32(pkt->data) == AV_RL32("RIFF"))61 if (AV_RL32(pkt->data) == AV_RL32("RIFF"))
63 skip = 12;62 skip = 12;
64 63 // Safe to do this as a valid WebP bitstream is >=30 bytes.
65 if (pkt->size < skip + 4)64 if (pkt->size < skip + 4)
66 return 0;65 return AVERROR_INVALIDDATA;
67 if (AV_RL32(pkt->data + skip) == AV_RL32("VP8X")) {66 if (AV_RL32(pkt->data + skip) == AV_RL32("VP8X")) {
68 flags |= pkt->data[skip + 4 + 4];67 flags |= pkt->data[skip + 4 + 4];
69 }68 }
70 69
71 if (flags & 2) // ANIMATION_FLAG is on70 if (flags & 2) // ANIMATION_FLAG is on
72 return 1;71 return 1;
73 }
74 return 0;72 return 0;
75}73}
76 74
@@ -84,13 +82,9 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts) · 7 unmodified lines
84 unsigned flags = 0;82 unsigned flags = 0;
85 int vp8x = 0;83 int vp8x = 0;
86 84
87 if (w->last_pkt.size < 4)
88 return 0;
89 if (AV_RL32(w->last_pkt.data) == AV_RL32("RIFF"))85 if (AV_RL32(w->last_pkt.data) == AV_RL32("RIFF"))
90 skip = 12;86 skip = 12;
91 87
92 if (w->last_pkt.size < skip + 4)
93 return 0; // Safe to do this as a valid WebP bitstream is >=30 bytes.
94 if (AV_RL32(w->last_pkt.data + skip) == AV_RL32("VP8X")) {88 if (AV_RL32(w->last_pkt.data + skip) == AV_RL32("VP8X")) {
95 flags |= w->last_pkt.data[skip + 4 + 4];89 flags |= w->last_pkt.data[skip + 4 + 4];
96 vp8x = 1;90 vp8x = 1;
@@ -149,7 +143,14 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts) · 52 unmodified lines
149static int webp_write_packet(AVFormatContext *s, AVPacket *pkt)143static int webp_write_packet(AVFormatContext *s, AVPacket *pkt)
150{144{
151 WebpContext *w = s->priv_data;145 WebpContext *w = s->priv_data;
152 w->using_webp_anim_encoder |= is_animated_webp_packet(pkt);146 int ret;
147
148 if (!pkt->size)
149 return 0;
150 ret = is_animated_webp_packet(pkt);
151 if (ret < 0)
152 return ret;
153 w->using_webp_anim_encoder |= ret;
153 154
154 if (w->using_webp_anim_encoder) {155 if (w->using_webp_anim_encoder) {
155 avio_write(s->pb, pkt->data, pkt->size);156 avio_write(s->pb, pkt->data, pkt->size);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t