Coverage Report

Created: 2023-08-07 06:59

/src/p11-kit/common/url.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2011 Collabora Ltd.
3
 * Copyright (C) 2013 Red Hat Inc.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
7
 * are met:
8
 *
9
 *     * Redistributions of source code must retain the above
10
 *       copyright notice, this list of conditions and the
11
 *       following disclaimer.
12
 *     * Redistributions in binary form must reproduce the
13
 *       above copyright notice, this list of conditions and
14
 *       the following disclaimer in the documentation and/or
15
 *       other materials provided with the distribution.
16
 *     * The names of contributors to this software may not be
17
 *       used to endorse or promote products derived from this
18
 *       software without specific prior written permission.
19
 *
20
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30
 * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31
 * DAMAGE.
32
 *
33
 * Author: Stef Walter <stefw@collabora.co.uk>
34
 */
35
36
#include "config.h"
37
38
#include "debug.h"
39
#include "url.h"
40
41
#include <assert.h>
42
#include <ctype.h>
43
#include <stdlib.h>
44
#include <stdio.h>
45
#include <string.h>
46
47
const static char HEX_CHARS_UPPER[] = "0123456789ABCDEF";
48
const static char HEX_CHARS_LOWER[] = "0123456789abcdef";
49
50
unsigned char *
51
p11_url_decode (const char *value,
52
                const char *end,
53
                const char *skip,
54
                size_t *length)
55
0
{
56
0
  char *a, *b;
57
0
  unsigned char *result, *p;
58
59
0
  assert (value <= end);
60
0
  assert (skip != NULL);
61
62
  /* String can only get shorter */
63
0
  result = malloc ((end - value) + 1);
64
0
  return_val_if_fail (result != NULL, NULL);
65
66
  /* Now loop through looking for escapes */
67
0
  p = result;
68
0
  while (value != end) {
69
    /*
70
     * A percent sign followed by two hex digits means
71
     * that the digits represent an escaped character.
72
     */
73
0
    if (*value == '%') {
74
0
      value++;
75
0
      if (end - value < 2) {
76
0
        free (result);
77
0
        return NULL;
78
0
      }
79
0
      a = strchr (HEX_CHARS_UPPER, p11_ascii_toupper (value[0]));
80
0
      b = strchr (HEX_CHARS_UPPER, p11_ascii_toupper (value[1]));
81
0
      if (!a || !b) {
82
0
        free (result);
83
0
        return NULL;
84
0
      }
85
0
      *p = (a - HEX_CHARS_UPPER) << 4;
86
0
      *(p++) |= (b - HEX_CHARS_UPPER);
87
0
      value += 2;
88
89
    /* Ignore whitespace characters */
90
0
    } else if (strchr (skip, *value)) {
91
0
      value++;
92
93
    /* A different character */
94
0
    } else {
95
0
      *(p++) = *(value++);
96
0
    }
97
0
  }
98
99
  /* Null terminate string, in case its a string */
100
0
  *p = 0;
101
102
0
  if (length)
103
0
    *length = p - result;
104
0
  return result;
105
0
}
106
107
void
108
p11_url_encode (const unsigned char *value,
109
                const unsigned char *end,
110
                const char *verbatim,
111
                p11_buffer *buf)
112
0
{
113
0
  char hex[3];
114
0
  const char *env;
115
0
  const char *hex_chars;
116
117
0
  assert (value <= end);
118
119
  /* Opt to output lowercase hex-digits for compatibility */
120
0
  env = secure_getenv ("P11_KIT_URI_LOWERCASE");
121
0
  if (env && *env != '\0')
122
0
    hex_chars = HEX_CHARS_LOWER;
123
0
  else
124
0
    hex_chars = HEX_CHARS_UPPER;
125
126
  /* Now loop through looking for escapes */
127
0
  while (value != end) {
128
129
    /* These characters we let through verbatim */
130
0
    if (*value && strchr (verbatim, *value) != NULL) {
131
0
      p11_buffer_add (buf, value, 1);
132
133
    /* All others get encoded */
134
0
    } else {
135
0
      hex[0] = '%';
136
0
      hex[1] = hex_chars[((unsigned char)*value) >> 4];
137
0
      hex[2] = hex_chars[((unsigned char)*value) & 0x0F];
138
0
      p11_buffer_add (buf, hex, 3);
139
0
    }
140
141
0
    ++value;
142
0
  }
143
0
}