Coverage Report

Created: 2026-06-30 06:59

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/p11-kit/common/url.c
Line
Count
Source
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
144k
{
56
144k
  const char *a, *b;
57
144k
  unsigned char *result, *p;
58
59
144k
  assert (value <= end);
60
144k
  assert (skip != NULL);
61
62
  /* String can only get shorter */
63
144k
  result = malloc ((end - value) + 1);
64
144k
  return_val_if_fail (result != NULL, NULL);
65
66
  /* Now loop through looking for escapes */
67
144k
  p = result;
68
10.3M
  while (value != end) {
69
    /*
70
     * A percent sign followed by two hex digits means
71
     * that the digits represent an escaped character.
72
     */
73
10.1M
    if (*value == '%') {
74
1.68k
      value++;
75
1.68k
      if (end - value < 2) {
76
15
        free (result);
77
15
        return NULL;
78
15
      }
79
1.66k
      a = strchr (HEX_CHARS_UPPER, p11_ascii_toupper (value[0]));
80
1.66k
      b = strchr (HEX_CHARS_UPPER, p11_ascii_toupper (value[1]));
81
1.66k
      if (!a || !b) {
82
38
        free (result);
83
38
        return NULL;
84
38
      }
85
1.62k
      *p = (a - HEX_CHARS_UPPER) << 4;
86
1.62k
      *(p++) |= (b - HEX_CHARS_UPPER);
87
1.62k
      value += 2;
88
89
    /* Ignore whitespace characters */
90
10.1M
    } else if (strchr (skip, *value)) {
91
0
      value++;
92
93
    /* A different character */
94
10.1M
    } else {
95
10.1M
      *(p++) = *(value++);
96
10.1M
    }
97
10.1M
  }
98
99
  /* Null terminate string, in case its a string */
100
144k
  *p = 0;
101
102
144k
  if (length)
103
3.38k
    *length = p - result;
104
144k
  return result;
105
144k
}
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
81.8k
{
113
81.8k
  char hex[3];
114
81.8k
  const char *env;
115
81.8k
  const char *hex_chars;
116
117
81.8k
  assert (value <= end);
118
119
  /* Opt to output lowercase hex-digits for compatibility */
120
81.8k
  env = secure_getenv ("P11_KIT_URI_LOWERCASE");
121
81.8k
  if (env && *env != '\0')
122
0
    hex_chars = HEX_CHARS_LOWER;
123
81.8k
  else
124
81.8k
    hex_chars = HEX_CHARS_UPPER;
125
126
  /* Now loop through looking for escapes */
127
3.86M
  while (value != end) {
128
129
    /* These characters we let through verbatim */
130
3.78M
    if (*value && strchr (verbatim, *value) != NULL) {
131
437k
      p11_buffer_add (buf, value, 1);
132
133
    /* All others get encoded */
134
3.34M
    } else {
135
3.34M
      hex[0] = '%';
136
3.34M
      hex[1] = hex_chars[((unsigned char)*value) >> 4];
137
3.34M
      hex[2] = hex_chars[((unsigned char)*value) & 0x0F];
138
3.34M
      p11_buffer_add (buf, hex, 3);
139
3.34M
    }
140
141
3.78M
    ++value;
142
3.78M
  }
143
81.8k
}