LCOV - code coverage report
Current view: top level - src/libavformat - data_uri.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 50 0.0 %
Date: 2017-01-24 04:42:20 Functions: 0 3 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2012 Nicolas George
       3             :  *
       4             :  * This file is part of FFmpeg.
       5             :  *
       6             :  * FFmpeg is free software; you can redistribute it and/or
       7             :  * modify it under the terms of the GNU Lesser General Public License
       8             :  * as published by the Free Software Foundation; either
       9             :  * version 2.1 of the License, or (at your option) any later version.
      10             :  *
      11             :  * FFmpeg is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU Lesser General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public License
      17             :  * along with FFmpeg; if not, write to the Free Software Foundation, Inc.,
      18             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      19             :  */
      20             : 
      21             : #include <string.h>
      22             : #include "libavutil/avstring.h"
      23             : #include "libavutil/base64.h"
      24             : #include "url.h"
      25             : 
      26             : typedef struct {
      27             :     const uint8_t *data;
      28             :     void *tofree;
      29             :     size_t size;
      30             :     size_t pos;
      31             : } DataContext;
      32             : 
      33           0 : static av_cold int data_open(URLContext *h, const char *uri, int flags)
      34             : {
      35           0 :     DataContext *dc = h->priv_data;
      36             :     const char *data, *opt, *next;
      37             :     char *ddata;
      38           0 :     int ret, base64 = 0;
      39             :     size_t in_size;
      40             : 
      41             :     /* data:content/type[;base64],payload */
      42             : 
      43           0 :     av_strstart(uri, "data:", &uri);
      44           0 :     data = strchr(uri, ',');
      45           0 :     if (!data) {
      46           0 :         av_log(h, AV_LOG_ERROR, "No ',' delimiter in URI\n");
      47           0 :         return AVERROR(EINVAL);
      48             :     }
      49           0 :     opt = uri;
      50           0 :     while (opt < data) {
      51           0 :         next = av_x_if_null(memchr(opt, ';', data - opt), data);
      52           0 :         if (opt == uri) {
      53           0 :             if (!memchr(opt, '/', next - opt)) { /* basic validity check */
      54           0 :                 av_log(h, AV_LOG_ERROR, "Invalid content-type '%.*s'\n",
      55           0 :                        (int)(next - opt), opt);
      56           0 :                 return AVERROR(EINVAL);
      57             :             }
      58           0 :             av_log(h, AV_LOG_VERBOSE, "Content-type: %.*s\n",
      59           0 :                    (int)(next - opt), opt);
      60             :         } else {
      61           0 :             if (!av_strncasecmp(opt, "base64", next - opt)) {
      62           0 :                 base64 = 1;
      63             :             } else {
      64           0 :                 av_log(h, AV_LOG_VERBOSE, "Ignoring option '%.*s'\n",
      65           0 :                        (int)(next - opt), opt);
      66             :             }
      67             :         }
      68           0 :         opt = next + 1;
      69             :     }
      70             : 
      71           0 :     data++;
      72           0 :     in_size = strlen(data);
      73           0 :     if (base64) {
      74           0 :         size_t out_size = 3 * (in_size / 4) + 1;
      75             : 
      76           0 :         if (out_size > INT_MAX || !(ddata = av_malloc(out_size)))
      77           0 :             return AVERROR(ENOMEM);
      78           0 :         if ((ret = av_base64_decode(ddata, data, out_size)) < 0) {
      79           0 :             av_free(ddata);
      80           0 :             av_log(h, AV_LOG_ERROR, "Invalid base64 in URI\n");
      81           0 :             return ret;
      82             :         }
      83           0 :         dc->data = dc->tofree = ddata;
      84           0 :         dc->size = ret;
      85             :     } else {
      86           0 :         dc->data = data;
      87           0 :         dc->size = in_size;
      88             :     }
      89           0 :     return 0;
      90             : }
      91             : 
      92           0 : static av_cold int data_close(URLContext *h)
      93             : {
      94           0 :     DataContext *dc = h->priv_data;
      95             : 
      96           0 :     av_freep(&dc->tofree);
      97           0 :     return 0;
      98             : }
      99             : 
     100           0 : static int data_read(URLContext *h, unsigned char *buf, int size)
     101             : {
     102           0 :     DataContext *dc = h->priv_data;
     103             : 
     104           0 :     if (dc->pos >= dc->size)
     105           0 :         return AVERROR_EOF;
     106           0 :     size = FFMIN(size, dc->size - dc->pos);
     107           0 :     memcpy(buf, dc->data + dc->pos, size);
     108           0 :     dc->pos += size;
     109           0 :     return size;
     110             : }
     111             : 
     112             : const URLProtocol ff_data_protocol = {
     113             :     .name           = "data",
     114             :     .url_open       = data_open,
     115             :     .url_close      = data_close,
     116             :     .url_read       = data_read,
     117             :     .priv_data_size = sizeof(DataContext),
     118             : };

Generated by: LCOV version 1.12