diff mbox

[FFmpeg-devel] lavc/pnmdec: Do not fail by default for truncated pbm files

Message ID 201609042058.44816.cehoyos@ag.or.at
State Superseded
Headers show

Commit Message

Carl Eugen Hoyos Sept. 4, 2016, 6:58 p.m. UTC
Hi!

Some scanner - scannersoftware combination (HP_Officejet_Pro_X476dn_MFP 
- sane) truncates trailing zeros in pbm files and FreeImage (a library 
used in free and proprietary image software) reads such files.
Attached patch copies this behaviour and fixes ticket #5795.

Please comment, Carl Eugen
From af00c56b38b28e07bbba46031472da41300a8cf1 Mon Sep 17 00:00:00 2001
From: Carl Eugen Hoyos <cehoyos@ag.or.at>
Date: Sun, 4 Sep 2016 20:52:28 +0200
Subject: [PATCH] lavc/pnmdec: Do not abort by default for truncated pbm
 files.

Fixes ticket #5795.
---
 libavcodec/pnmdec.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

Comments

Michael Niedermayer Sept. 5, 2016, 7:21 a.m. UTC | #1
On Sun, Sep 04, 2016 at 08:58:44PM +0200, Carl Eugen Hoyos wrote:
> Hi!
> 
> Some scanner - scannersoftware combination (HP_Officejet_Pro_X476dn_MFP 
> - sane) truncates trailing zeros in pbm files and FreeImage (a library 
> used in free and proprietary image software) reads such files.
> Attached patch copies this behaviour and fixes ticket #5795.
> 
> Please comment, Carl Eugen

>  pnmdec.c |   10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> fd31d6d029cade2e5eb2f2a705067cdaa2ab02d5  0001-lavc-pnmdec-Do-not-abort-by-default-for-truncated-pb.patch
> From af00c56b38b28e07bbba46031472da41300a8cf1 Mon Sep 17 00:00:00 2001
> From: Carl Eugen Hoyos <cehoyos@ag.or.at>
> Date: Sun, 4 Sep 2016 20:52:28 +0200
> Subject: [PATCH] lavc/pnmdec: Do not abort by default for truncated pbm
>  files.
> 
> Fixes ticket #5795.
> ---
>  libavcodec/pnmdec.c |   10 ++++++++--
>  1 file changed, 8 insertions(+), 2 deletions(-)
> 
> diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c
> index d4261a4..0b7a0f6 100644
> --- a/libavcodec/pnmdec.c
> +++ b/libavcodec/pnmdec.c
> @@ -124,8 +124,12 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
>      do_read:
>          ptr      = p->data[0];
>          linesize = p->linesize[0];
> -        if (s->bytestream + n * avctx->height > s->bytestream_end)
> -            return AVERROR_INVALIDDATA;
> +        if (s->bytestream + n * avctx->height > s->bytestream_end) {
> +            av_log(avctx, AV_LOG_ERROR,
> +                   "Invalid truncated file\n");
> +            if (avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT)
> +                return AVERROR_INVALIDDATA;
> +        }
>          if(s->type < 4 || (is_mono && s->type==7)){
>              for (i=0; i<avctx->height; i++) {
>                  PutBitContext pb;

> @@ -159,6 +163,8 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data,
>              }
>          }else{
>          for (i = 0; i < avctx->height; i++) {
> +            if (s->bytestream + n > s->bytestream_end)
> +                continue;

having a pointer point outside of 0..array length is undefined
behaviour (and can overflow in principle)


[...]
diff mbox

Patch

diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c
index d4261a4..0b7a0f6 100644
--- a/libavcodec/pnmdec.c
+++ b/libavcodec/pnmdec.c
@@ -124,8 +124,12 @@  static int pnm_decode_frame(AVCodecContext *avctx, void *data,
     do_read:
         ptr      = p->data[0];
         linesize = p->linesize[0];
-        if (s->bytestream + n * avctx->height > s->bytestream_end)
-            return AVERROR_INVALIDDATA;
+        if (s->bytestream + n * avctx->height > s->bytestream_end) {
+            av_log(avctx, AV_LOG_ERROR,
+                   "Invalid truncated file\n");
+            if (avctx->strict_std_compliance >= FF_COMPLIANCE_STRICT)
+                return AVERROR_INVALIDDATA;
+        }
         if(s->type < 4 || (is_mono && s->type==7)){
             for (i=0; i<avctx->height; i++) {
                 PutBitContext pb;
@@ -159,6 +163,8 @@  static int pnm_decode_frame(AVCodecContext *avctx, void *data,
             }
         }else{
         for (i = 0; i < avctx->height; i++) {
+            if (s->bytestream + n > s->bytestream_end)
+                continue;
             if (!upgrade)
                 samplecpy(ptr, s->bytestream, n, s->maxval);
             else if (upgrade == 1) {