Re: [FFmpeg-devel] [PATCH] fix http chunk encoding parsing

2016-03-12 Thread Michael Niedermayer
On Tue, Dec 15, 2015 at 12:31:18PM +0300, Eugene Kosov wrote:
> ---
>  ffserver.c | 77 
> --
>  1 file changed, 50 insertions(+), 27 deletions(-)

sorry for the late reply

please explain what exactly this patch fixes and how to reproduce it

thx

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

I am the wisest man alive, for I know one thing, and that is that I know
nothing. -- Socrates


signature.asc
Description: Digital signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] fix http chunk encoding parsing

2015-12-15 Thread Eugene Kosov
---
 ffserver.c | 77 --
 1 file changed, 50 insertions(+), 27 deletions(-)

diff --git a/ffserver.c b/ffserver.c
index 029771c..b7f9616 100644
--- a/ffserver.c
+++ b/ffserver.c
@@ -138,7 +138,7 @@ typedef struct HTTPContext {
 int http_error;
 int post;
 int chunked_encoding;
-int chunk_size;   /* 0 if it needs to be read */
+int chunk_size; /* 0 if it needs to be read; negative if reading chunk 
footer */
 struct HTTPContext *next;
 int got_key_frame; /* stream 0 => 1, stream 1 => 2, stream 2=> 4 */
 int64_t data_count;
@@ -2598,36 +2598,37 @@ static int http_receive_data(HTTPContext *c)
 {
 HTTPContext *c1;
 int len, loop_run = 0;
+char buf[16];
+int buf_len = 0;
+
+if (c->chunked_encoding && c->chunk_size == 0) {
+for (;;) {
+/* read chunk header, if present */
+len = recv(c->fd, buf + buf_len, 1, 0);
+buf_len += len;
+
+if (len < 0) {
+if (ff_neterrno() != AVERROR(EAGAIN) &&
+ff_neterrno() != AVERROR(EINTR))
+/* error : close connection */
+goto fail;
+return 0;
+}
 
-while (c->chunked_encoding && !c->chunk_size &&
-   c->buffer_end > c->buffer_ptr) {
-/* read chunk header, if present */
-len = recv(c->fd, c->buffer_ptr, 1, 0);
-
-if (len < 0) {
-if (ff_neterrno() != AVERROR(EAGAIN) &&
-ff_neterrno() != AVERROR(EINTR))
-/* error : close connection */
+if (len == 0 || ++loop_run > 10)
+/* end of connection or no chunk size : close it */
 goto fail;
-return 0;
-} else if (len == 0) {
-/* end of connection : close it */
-goto fail;
-} else if (c->buffer_ptr - c->buffer >= 2 &&
-   !memcmp(c->buffer_ptr - 1, "\r\n", 2)) {
-c->chunk_size = strtol(c->buffer, 0, 16);
-if (c->chunk_size == 0) // end of stream
-goto fail;
-c->buffer_ptr = c->buffer;
-break;
-} else if (++loop_run > 10)
-/* no chunk header, abort */
-goto fail;
-else
-c->buffer_ptr++;
+
+if (buf_len > 1 && !memcmp(buf + buf_len - 2, "\r\n", 2)) {
+c->chunk_size = strtol(buf, 0, 16);
+if (c->chunk_size == 0) // end of stream
+goto fail;
+break;
+}
+}
 }
 
-if (c->buffer_end > c->buffer_ptr) {
+if (c->buffer_end > c->buffer_ptr && c->chunk_size > 0) {
 len = recv(c->fd, c->buffer_ptr,
FFMIN(c->chunk_size, c->buffer_end - c->buffer_ptr), 0);
 if (len < 0) {
@@ -2644,6 +2645,28 @@ static int http_receive_data(HTTPContext *c)
 c->data_count += len;
 update_datarate(>datarate, c->data_count);
 }
+
+// Reading of chunk body is done. Now read 2 bytes of chunk footer.
+if (!c->chunk_size)
+c->chunk_size = -2;
+}
+
+if (c->chunked_encoding && c->chunk_size < 0) {
+while (c->chunk_size < 0) {
+len = recv(c->fd, buf, 1, 0);
+if (len < 0) {
+if (ff_neterrno() != AVERROR(EAGAIN) &&
+ff_neterrno() != AVERROR(EINTR))
+/* error : close connection */
+goto fail;
+return 0;
+}
+if (len == 0) {
+goto fail;
+}
+
+c->chunk_size += len;
+}
 }
 
 if (c->buffer_ptr - c->buffer >= 2 && c->data_count > FFM_PACKET_SIZE) {
-- 
2.5.0
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel