Coverage Report

Created: 2026-01-25 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ffmpeg/libavformat/urldecode.c
Line
Count
Source
1
/*
2
 * Simple URL decoding function
3
 * Copyright (c) 2012 Antti Seppälä
4
 *
5
 * References:
6
 *  RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
7
 *       T. Berners-Lee et al. The Internet Society, 2005
8
 *
9
 * based on http://www.icosaedro.it/apache/urldecode.c
10
 *          from Umberto Salsi (salsi@icosaedro.it)
11
 *
12
 * This file is part of FFmpeg.
13
 *
14
 * FFmpeg is free software; you can redistribute it and/or
15
 * modify it under the terms of the GNU Lesser General Public
16
 * License as published by the Free Software Foundation; either
17
 * version 2.1 of the License, or (at your option) any later version.
18
 *
19
 * FFmpeg is distributed in the hope that it will be useful,
20
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22
 * Lesser General Public License for more details.
23
 *
24
 * You should have received a copy of the GNU Lesser General Public
25
 * License along with FFmpeg; if not, write to the Free Software
26
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
27
 */
28
29
#include <string.h>
30
31
#include "libavutil/error.h"
32
#include "libavutil/macros.h"
33
#include "libavutil/mem.h"
34
#include "libavutil/avstring.h"
35
#include "urldecode.h"
36
37
static size_t urldecode(char *dest, const char *url, size_t url_len, int decode_plus_sign)
38
0
{
39
0
    size_t s = 0, d = 0;
40
0
    char c;
41
42
0
    while (s < url_len) {
43
0
        c = url[s++];
44
45
0
        if (c == '%' && s + 1 < url_len) {
46
0
            char c2 = url[s++];
47
0
            char c3 = url[s++];
48
0
            if (av_isxdigit(c2) && av_isxdigit(c3)) {
49
0
                c2 = av_tolower(c2);
50
0
                c3 = av_tolower(c3);
51
52
0
                if (c2 <= '9')
53
0
                    c2 = c2 - '0';
54
0
                else
55
0
                    c2 = c2 - 'a' + 10;
56
57
0
                if (c3 <= '9')
58
0
                    c3 = c3 - '0';
59
0
                else
60
0
                    c3 = c3 - 'a' + 10;
61
62
0
                dest[d++] = 16 * c2 + c3;
63
64
0
            } else { /* %zz or something other invalid */
65
0
                dest[d++] = c;
66
0
                dest[d++] = c2;
67
0
                dest[d++] = c3;
68
0
            }
69
0
        } else if (c == '+' && decode_plus_sign) {
70
0
            dest[d++] = ' ';
71
0
        } else {
72
0
            dest[d++] = c;
73
0
        }
74
75
0
    }
76
77
0
    return d;
78
0
}
79
80
char *ff_urldecode(const char *url, int decode_plus_sign)
81
0
{
82
0
    char *dest = NULL;
83
0
    size_t url_len;
84
85
0
    if (!url)
86
0
        return NULL;
87
88
0
    url_len = strlen(url) + 1;
89
0
    dest = av_malloc(url_len);
90
91
0
    if (!dest)
92
0
        return NULL;
93
94
0
    urldecode(dest, url, url_len, decode_plus_sign);
95
96
0
    return dest;
97
0
}
98
99
int ff_urldecode_len(char *dest, size_t dest_len, const char *url, size_t url_max_len, int decode_plus_sign)
100
0
{
101
0
    size_t written_bytes;
102
0
    size_t url_len = strlen(url);
103
104
0
    url_len = FFMIN(url_len, url_max_len);
105
106
0
    if (dest_len <= url_len)
107
0
        return AVERROR(EINVAL);
108
109
0
    written_bytes = urldecode(dest, url, url_len, decode_plus_sign);
110
0
    dest[written_bytes] = '\0';
111
112
0
    return written_bytes;
113
0
}