Coverage Report

Created: 2023-03-26 07:33

/src/gnutls/lib/pathbuf.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2010-2022 Free Software Foundation, Inc.
3
 * Copyright (C) 2022 Red Hat, Inc.
4
 *
5
 * Author: Daiki Ueno
6
 *
7
 * This file is part of GnuTLS.
8
 *
9
 * The GnuTLS is free software; you can redistribute it and/or
10
 * modify it under the terms of the GNU Lesser General Public License
11
 * as published by the Free Software Foundation; either version 2.1 of
12
 * the License, or (at your option) any later version.
13
 *
14
 * This library is distributed in the hope that it will be useful, but
15
 * WITHOUT ANY WARRANTY; without even the implied warranty of
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17
 * Lesser General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU Lesser General Public License
20
 * along with this program.  If not, see <https://www.gnu.org/licenses/>
21
 *
22
 */
23
24
#include "config.h"
25
26
#include "pathbuf.h"
27
#include "gnutls_int.h"
28
#include <limits.h>
29
#include "intprops.h"
30
31
static int pathbuf_reserve(struct gnutls_pathbuf_st *buffer, size_t to_add)
32
0
{
33
0
  size_t len;
34
0
  char *ptr;
35
36
0
  len = buffer->len;
37
38
0
  if (INT_ADD_OVERFLOW(len, to_add)) {
39
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
40
0
  }
41
0
  len += to_add;
42
43
  /* NUL terminator.  */
44
0
  if (INT_ADD_OVERFLOW(len, 1)) {
45
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
46
0
  }
47
0
  len++;
48
49
0
  if (len <= buffer->cap) {
50
0
    return 0;
51
0
  }
52
53
0
  if (buffer->ptr == buffer->base) {
54
0
    ptr = gnutls_strdup(buffer->ptr);
55
0
    if (!ptr) {
56
0
      return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
57
0
    }
58
0
    buffer->ptr = ptr;
59
0
  }
60
61
0
  ptr = gnutls_realloc(buffer->ptr, len);
62
0
  if (!ptr) {
63
0
    return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
64
0
  }
65
66
0
  buffer->ptr = ptr;
67
0
  buffer->cap = len;
68
69
0
  return 0;
70
0
}
71
72
int _gnutls_pathbuf_init(struct gnutls_pathbuf_st *buffer, const char *base)
73
0
{
74
0
  size_t len;
75
0
  int ret;
76
77
0
  memset(buffer, 0, sizeof(*buffer));
78
0
  buffer->cap = sizeof(buffer->base);
79
0
  buffer->ptr = buffer->base;
80
81
0
  len = strlen(base);
82
83
0
  ret = pathbuf_reserve(buffer, len);
84
0
  if (ret < 0) {
85
0
    return ret;
86
0
  }
87
88
0
  strcpy(buffer->ptr, base);
89
0
  buffer->len = len;
90
91
0
  return 0;
92
0
}
93
94
int
95
_gnutls_pathbuf_append(struct gnutls_pathbuf_st *buffer, const char *component)
96
0
{
97
0
  size_t len;
98
0
  char *p;
99
0
  int ret;
100
101
0
  len = strlen(component);
102
103
  /* Path separator.  */
104
0
  if (INT_ADD_OVERFLOW(len, 1)) {
105
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
106
0
  }
107
0
  len++;
108
109
0
  ret = pathbuf_reserve(buffer, len);
110
0
  if (ret < 0) {
111
0
    return ret;
112
0
  }
113
114
0
  p = stpcpy(&buffer->ptr[buffer->len], "/");
115
0
  strcpy(p, component);
116
117
  /* Overflow is already checked in the call to pathbuf_reserve
118
   * above.
119
   */
120
0
  buffer->len += len;
121
122
0
  return 0;
123
0
}
124
125
int _gnutls_pathbuf_truncate(struct gnutls_pathbuf_st *buffer, size_t len)
126
0
{
127
0
  if (len > buffer->len) {
128
0
    return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST);
129
0
  }
130
0
  buffer->len = len;
131
0
  buffer->ptr[len] = '\0';
132
0
  return 0;
133
0
}
134
135
void _gnutls_pathbuf_deinit(struct gnutls_pathbuf_st *buffer)
136
0
{
137
0
  if (buffer->ptr != buffer->base) {
138
0
    gnutls_free(buffer->ptr);
139
0
  }
140
0
  memset(buffer, 0, sizeof(*buffer));
141
0
}