[FFmpeg-devel] theora depayloader

Martin Storsjö martin
Sat Mar 20 11:47:28 CET 2010


On Sat, 20 Mar 2010, Josh Allmann wrote:

> On 19 March 2010 21:19, Martin Storsj? <martin at martin.st> wrote:
> > On Fri, 19 Mar 2010, Josh Allmann wrote:
> >
> >
> >> + ? ? ? ? ? ?data_len += pkt_len;
> >> + ? ? ? ? ? ?len -= pkt_len+2;
> >> + ? ? ? }
> >> +
> >> + ? ? ? if (len < 0){
> >> + ? ? ? ? ?av_log(ctx, AV_LOG_ERROR,
> >> + ? ? ? ? ? ? ? ? "Length overread by %d\n", -len);
> >> + ? ? ? }
> >
> > Here, you could potentially get the case where len reaches exactly zero,
> > before i has reached num_pkts, so we'd get no warning even if the packet
> > was invalid...
> 
> Hm, good catch. Fixed by checking for len >= 0 in the for loop.
> 
> Now that I think of it, a bad packet could potentially give us a large
> negative pkt_len, which would in turn make len positive, but still
> invalid... so I changed the type declaration of pkt_len (and related
> header vars) to uint32_t.
> 
> I have not explicitly tested for these conditions, though.
> 
> Also added a return AVERROR_INVALIDDATA; I forgot that.


> +        // fast first pass to calculate total length
> +        for (i = 0, data_len = 0;  (i < num_pkts) && (len >= 0);  i++) {
> +            int off   = data_len + (i << 1);
> +            pkt_len   = AV_RB16(buf + off);
> +            data_len += pkt_len;
> +            len      -= pkt_len + 2;
> +        }
> +
> +        if (len < 0) {
> +            av_log(ctx, AV_LOG_ERROR, "Length overread by %d\n", -len);
> +            return AVERROR_INVALIDDATA;
> +        }

If len == 0 or 1, you will read outside of the buffer (which isn't a 
padded buffer IIRC). What about this loop condition instead:

for (...; i < num_pkts && len >= 2; i++)

and check for errors with:

if (len < 0 || i < num_pkts)

That is, if we've errored out due to the length restriction, i will be 
left at less than num_pkts, and we haven't parsed everything => error.


> +        pkt->stream_index = st->index;
> +
> +       // concatenate frames
> +        for (i = 0, write_len = 0; write_len < data_len; i++) {

Indentation off on the comment.

> +        if((res = url_open_dyn_buf(&data->fragment)) < 0)

Space after if

> +    num_packed         = bytestream_get_be32(&packed_headers);
> +    theora_data->ident = bytestream_get_be24(&packed_headers);
> +    length             = bytestream_get_be16(&packed_headers);

No checking if there's sufficient bytes to read - check e.g. 
packed_headers_end - packed_headers >= 9 before this.

> +int ff_theora_parse_fmtp_config(AVCodecContext * codec,
> +                                void *theora_data, char *attr, char *value)
> +{
> +  int result = 0;
> +  assert(codec->id == CODEC_ID_THEORA);
> +  assert(theora_data);
> +
> +  if (!strcmp(attr, "sampling")) {
> +    return AVERROR_PATCHWELCOME;
> +  } else if (!strcmp(attr, "width")) {

The indentation seems to be off in the whole function

// Martin



More information about the ffmpeg-devel mailing list