Merge commit '225e84e74544062706c0159ec0737b0e1d40915f'
authorDerek Buitenhuis <derek.buitenhuis@gmail.com>
Mon, 29 Feb 2016 15:50:32 +0000 (15:50 +0000)
committerDerek Buitenhuis <derek.buitenhuis@gmail.com>
Mon, 29 Feb 2016 15:50:32 +0000 (15:50 +0000)
* commit '225e84e74544062706c0159ec0737b0e1d40915f':
  hls: disallow opening nested files in child demuxers

Merged-by: Derek Buitenhuis <derek.buitenhuis@gmail.com>
1  2 
libavformat/hls.c

@@@ -1484,9 -494,18 +1484,19 @@@ static int save_avio_options(AVFormatCo
      return ret;
  }
  
+ static int nested_io_open(AVFormatContext *s, AVIOContext **pb, const char *url,
+                           int flags, AVDictionary **opts)
+ {
+     av_log(s, AV_LOG_ERROR,
+            "A HLS playlist item '%s' referred to an external file '%s'. "
+            "Opening this file was forbidden for security reasons\n",
+            s->filename, url);
+     return AVERROR(EPERM);
+ }
  static int hls_read_header(AVFormatContext *s)
  {
 +    void *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque;
      HLSContext *c = s->priv_data;
      int ret = 0, i, j, stream_offset = 0;
  
               * so avformat_close_input shouldn't be called. If
               * avformat_open_input fails below, it frees and zeros the
               * context, so it doesn't need any special treatment like this. */
 -            avformat_free_context(v->ctx);
 -            v->ctx = NULL;
 +            av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", pls->segments[0]->url);
 +            avformat_free_context(pls->ctx);
 +            pls->ctx = NULL;
              goto fail;
          }
 -        v->ctx->pb       = &v->pb;
 -        v->ctx->io_open  = nested_io_open;
 -        v->stream_offset = stream_offset;
 -        ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL);
 -        if (ret < 0)
 +        pls->ctx->pb       = &pls->pb;
++        pls->ctx->io_open  = nested_io_open;
 +        pls->stream_offset = stream_offset;
 +
 +        if ((ret = ff_copy_whitelists(pls->ctx, s)) < 0)
              goto fail;
  
 -        v->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
 -        ret = avformat_find_stream_info(v->ctx, NULL);
 +        ret = avformat_open_input(&pls->ctx, pls->segments[0]->url, in_fmt, NULL);
          if (ret < 0)
              goto fail;
 -        snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth);
  
 -        program = av_new_program(s, i);
 -        if (!program)
 +        if (pls->id3_deferred_extra && pls->ctx->nb_streams == 1) {
 +            ff_id3v2_parse_apic(pls->ctx, &pls->id3_deferred_extra);
 +            avformat_queue_attached_pictures(pls->ctx);
 +            ff_id3v2_free_extra_meta(&pls->id3_deferred_extra);
 +            pls->id3_deferred_extra = NULL;
 +        }
 +
 +        pls->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER;
 +        ret = avformat_find_stream_info(pls->ctx, NULL);
 +        if (ret < 0)
              goto fail;
 -        av_dict_set(&program->metadata, "variant_bitrate", bitrate_str, 0);
  
 -        /* Create new AVStreams for each stream in this variant */
 -        for (j = 0; j < v->ctx->nb_streams; j++) {
 +        if (pls->is_id3_timestamped == -1)
 +            av_log(s, AV_LOG_WARNING, "No expected HTTP requests have been made\n");
 +
 +        /* Create new AVStreams for each stream in this playlist */
 +        for (j = 0; j < pls->ctx->nb_streams; j++) {
              AVStream *st = avformat_new_stream(s, NULL);
 -            AVStream *ist = v->ctx->streams[j];
 +            AVStream *ist = pls->ctx->streams[j];
              if (!st) {
                  ret = AVERROR(ENOMEM);
                  goto fail;