Browse code

avformat/rmdec: when reading audio blocks, dont leave holes when reading fails

The fate test is changed because the reference file depends on the use of
non cleared data at the very
end. Alternatively we could upload a new reference file, though that would
then have to be changed every time the handling of a truncated frame changes
or theres a change to error concealment, each time adding a new file ...

Fixes use of uninitialized memory
Fixed: msan_uninit-mem_7f3c02b81363_2787_RLG2_19.rm
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Michael Niedermayer authored on 2014/01/10 06:59:51
Showing 2 changed files
... ...
@@ -789,6 +789,16 @@ rm_ac3_swap_bytes (AVStream *st, AVPacket *pkt)
789 789
     }
790 790
 }
791 791
 
792
+static int readfull(AVFormatContext *s, AVIOContext *pb, uint8_t *dst, int n) {
793
+    int ret = avio_read(pb, dst, n);
794
+    if (ret != n) {
795
+        if (ret >= 0) memset(dst + ret, 0, n - ret);
796
+        else          memset(dst      , 0, n);
797
+        av_log(s, AV_LOG_ERROR, "Failed to fully read block\n");
798
+    }
799
+    return ret;
800
+}
801
+
792 802
 int
793 803
 ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,
794 804
                     AVStream *st, RMStream *ast, int len, AVPacket *pkt,
... ...
@@ -821,14 +831,14 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb,
821 821
             switch (ast->deint_id) {
822 822
                 case DEINT_ID_INT4:
823 823
                     for (x = 0; x < h/2; x++)
824
-                        avio_read(pb, ast->pkt.data+x*2*w+y*cfs, cfs);
824
+                        readfull(s, pb, ast->pkt.data+x*2*w+y*cfs, cfs);
825 825
                     break;
826 826
                 case DEINT_ID_GENR:
827 827
                     for (x = 0; x < w/sps; x++)
828
-                        avio_read(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);
828
+                        readfull(s, pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps);
829 829
                     break;
830 830
                 case DEINT_ID_SIPR:
831
-                    avio_read(pb, ast->pkt.data + y * w, w);
831
+                    readfull(s, pb, ast->pkt.data + y * w, w);
832 832
                     break;
833 833
             }
834 834
 
... ...
@@ -31,8 +31,9 @@ fate-sipr-8k5: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_8k5.rm
31 31
 fate-sipr-8k5: REF = $(SAMPLES)/sipr/sipr_8k5.pcm
32 32
 
33 33
 FATE_SIPR += fate-sipr-16k
34
-fate-sipr-16k: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_16k.rm
34
+fate-sipr-16k: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_16k.rm -aframes 3250
35 35
 fate-sipr-16k: REF = $(SAMPLES)/sipr/sipr_16k.pcm
36
+fate-sipr-16k: SIZE_TOLERANCE = 40000
36 37
 
37 38
 $(FATE_SIPR): CMP = oneoff
38 39