[Ffmpeg-devel] [PATCH] read pnm header correctly on buffer boundary

Christian Linhart chris
Sun Jun 18 00:05:27 CEST 2006


I have encountered a bug which is triggered
when using an image2pipe consisting of a lot of ppm images as input.
The behavior is that the encoding stops with an error message.
(older versions of ffmpeg continued
to run with full CPU usage but doing nothing else)

I debugged this and found out the following:
The reason was that pnm_decode_header always assumes
that the current buffer contains enough data to hold the entire header.
With a longer image2pipe the chances are very high
that in some place, there is an end of buffer just inside the 
PNM-header, so
parsing the PNM-header fails due to the missing data.
(I reproduced it with a sequence of about 4000 images
of resolution 1280x1024 --> this is more than 15GB of raw data.)

I fixed the bug by making sure that pnm_decode_header
gets at least 32 Bytes of real data.

The patch below contains this fix as well as two new Debug-messages
which give feedback on problems with decoding a pnm-header.

The patch is versus an svn version which is a few hours old.
It said "Checked out revision 5493." after checking out the current version.

If you need test-data for reproducing the problem or for verifying my 
patch, please tell me.



Christian Linhart

Since I am new to this list, let me briefly introduce myself:
My name is Christian Linhart, I live in Salzburg/Austria which is in Europe.
I use Linux since kernel 0.99pl6.
I use ffmpeg as the encoder in most of the export filters of DemoRecorder
(in fact I use it in all export filters except in the FLV export filter.)

BTW, as soon as DemoRecorder is successful enough I consider donating to
the ffmpeg project. I didn't find instructions for donating and also
I read a one-year-old thread in the archives that there is currently
no defined way to donate to the project.
What is the current state of this topic?

Can you please insert DemoRecorder into the list of Projects Using FFmpeg?
The URL is: http://www.DemoRecorder.com
Thanks in advance.

P.P.P.S. here is the patch:
--- libavcodec/pnm.c    2006/06/17 19:34:25     1.1
+++ libavcodec/pnm.c    2006/06/17 20:35:55
@@ -162,22 +162,24 @@
     PNMContext * const s = avctx->priv_data;
     AVFrame *picture = data;
     AVFrame * const p= (AVFrame*)&s->picture;
     int i, n, linesize, h;
     unsigned char *ptr;
     s->bytestream= buf;
     s->bytestream_end= buf + buf_size;
-    if(pnm_decode_header(avctx, s) < 0)
+    if(pnm_decode_header(avctx, s) < 0) {
+       av_log(avctx, AV_LOG_DEBUG, "ffmpeg: pnm_decode_frame: 
pnm_decode_header error.\n");
         return -1;
+    }
         avctx->release_buffer(avctx, p);
     p->reference= 0;
     if(avctx->get_buffer(avctx, p) < 0){
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return -1;
     p->pict_type= FF_I_TYPE;
@@ -469,21 +471,25 @@
         pnmctx.bytestream= pc->buffer;
         pnmctx.bytestream_end= pc->buffer + pc->index;
         pnmctx.bytestream= (uint8_t *) buf; /* casts avoid warnings */
         pnmctx.bytestream_end= (uint8_t *) buf + buf_size;
-    if(pnm_decode_header(avctx, &pnmctx) < 0){
+    if ( pnmctx.bytestream_end - pnmctx.bytestream < 32 ) {
+       /* need more data for reading the header */
+       next = END_NOT_FOUND;
+    } else if(pnm_decode_header(avctx, &pnmctx) < 0){
+       av_log(avctx, AV_LOG_DEBUG, "ffmpeg: pnm_parse: 
pnm_decode_header error.\n");
         if(pnmctx.bytestream < pnmctx.bytestream_end){
             goto retry;
 #if 0

More information about the ffmpeg-devel mailing list