Coverage Report

Created: 2025-12-14 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/freeradius-server/src/freeradius-devel/io/pair.h
Line
Count
Source
1
#pragma once
2
/*
3
 *  This program is free software; you can redistribute it and/or modify
4
 *  it under the terms of the GNU General Public License as published by
5
 *  the Free Software Foundation; either version 2 of the License, or
6
 *  (at your option) any later version.
7
 *
8
 *  This program is distributed in the hope that it will be useful,
9
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *  GNU General Public License for more details.
12
 *
13
 *  You should have received a copy of the GNU General Public License
14
 *  along with this program; if not, write to the Free Software
15
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
16
 */
17
18
/**
19
 * $Id: 6f596aaa91c7d118164a98c7b9d69f076b75de1c $
20
 *
21
 * @file io/pair.h
22
 * @brief Encoder/decoder library interface
23
 *
24
 * @copyright 2017-2020 The FreeRADIUS project
25
 */
26
#include <freeradius-devel/util/dcursor.h>
27
#include <freeradius-devel/util/value.h>
28
#include <freeradius-devel/util/pair.h>
29
30
/** @name Encoder errors
31
 * @{
32
 */
33
34
/** Fatal encoding error
35
 */
36
392
#define PAIR_ENCODE_FATAL_ERROR SSIZE_MIN
37
38
/** @} */
39
40
/** @name Decode errors
41
 * @{
42
 */
43
/** Fatal error - Out of memory
44
 */
45
0
#define PAIR_DECODE_OOM   FR_VALUE_BOX_NET_OOM
46
47
/** Fatal error - Failed decoding the packet
48
 */
49
8.07k
#define PAIR_DECODE_FATAL_ERROR FR_VALUE_BOX_NET_ERROR
50
51
/** Return the correct adjusted slen for errors
52
 *
53
 * @param[in] slen  returned from the function we called.
54
 * @param[in] start of the buffer.
55
 * @param[in] p   offset passed to function which returned the slen.
56
 */
57
static inline ssize_t fr_pair_decode_slen(ssize_t slen, uint8_t const *start, uint8_t const *p)
58
402
{
59
402
  if (slen > 0) return slen;
60
61
402
  switch (slen) {
62
0
  case PAIR_DECODE_OOM:
63
112
  case PAIR_DECODE_FATAL_ERROR:
64
112
    return slen;
65
66
290
  default:
67
290
    return slen - (p - start);
68
402
  }
69
402
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer_util.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer_cbor.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer_der.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer_dns.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer_tacacs.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer_bfd.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer_radius.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer_tftp.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer_vmps.c:fr_pair_decode_slen
Unexecuted instantiation: encode.c:fr_pair_decode_slen
Unexecuted instantiation: struct.c:fr_pair_decode_slen
Unexecuted instantiation: fuzzer.c:fr_pair_decode_slen
Unexecuted instantiation: base.c:fr_pair_decode_slen
decode.c:fr_pair_decode_slen
Line
Count
Source
58
402
{
59
402
  if (slen > 0) return slen;
60
61
402
  switch (slen) {
62
0
  case PAIR_DECODE_OOM:
63
112
  case PAIR_DECODE_FATAL_ERROR:
64
112
    return slen;
65
66
290
  default:
67
290
    return slen - (p - start);
68
402
  }
69
402
}
Unexecuted instantiation: list.c:fr_pair_decode_slen
Unexecuted instantiation: packet.c:fr_pair_decode_slen
Unexecuted instantiation: tcp.c:fr_pair_decode_slen
Unexecuted instantiation: abinary.c:fr_pair_decode_slen
Unexecuted instantiation: vmps.c:fr_pair_decode_slen
70
71
/** Determine if the return code for an encoding function is a fatal error
72
 *
73
 */
74
static inline bool fr_pair_encode_is_error(ssize_t slen)
75
0
{
76
0
  if (slen == PAIR_ENCODE_FATAL_ERROR) return true;
77
0
  return false;
78
0
}
Unexecuted instantiation: fuzzer_dhcpv6.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer_util.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer_dhcpv4.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer_cbor.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer_der.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer_dns.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer_tacacs.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer_bfd.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer_radius.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer_tftp.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer_vmps.c:fr_pair_encode_is_error
Unexecuted instantiation: decode.c:fr_pair_encode_is_error
Unexecuted instantiation: encode.c:fr_pair_encode_is_error
Unexecuted instantiation: struct.c:fr_pair_encode_is_error
Unexecuted instantiation: fuzzer.c:fr_pair_encode_is_error
Unexecuted instantiation: base.c:fr_pair_encode_is_error
Unexecuted instantiation: list.c:fr_pair_encode_is_error
Unexecuted instantiation: packet.c:fr_pair_encode_is_error
Unexecuted instantiation: tcp.c:fr_pair_encode_is_error
Unexecuted instantiation: abinary.c:fr_pair_encode_is_error
Unexecuted instantiation: vmps.c:fr_pair_encode_is_error
79
80
/** Checks if we have sufficient buffer space, and returns how much space we'd need as a negative integer
81
 *
82
 */
83
#define FR_PAIR_ENCODE_HAVE_SPACE(_p, _end, _num) if (((_p) + (_num)) > (_end)) return (_end) - ((_p) + (_num));
84
85
/** @} */
86
87
/** Generic interface for encoding one or more fr_pair_ts
88
 *
89
 * An encoding function should consume at most, one top level fr_pair_t and encode
90
 * it in the appropriate wire format for the protocol, writing the encoded data to
91
 * out, and returning the encoded length.
92
 *
93
 * The exception to processing one fr_pair_t is if multiple fr_pair_ts can be aggregated
94
 * into a single TLV, in which case the encoder may consume as many fr_pair_ts as will
95
 * fit into that TLV.
96
 *
97
 * Outlen provides the length of the buffer to write the encoded data to.  The return
98
 * value must not be greater than outlen.
99
 *
100
 * The cursor is used to track how many pairs there are remaining.
101
 *
102
 * @param[out] out    Where to write the encoded data.
103
 * @param[in] cursor    Cursor containing the list of attributes to process.
104
 * @param[in] encode_ctx  Any encoder specific data such as secrets or configurables.
105
 * @return
106
 *  - PAIR_ENCODE_FATAL_ERROR - Encoding failed in a fatal way. Encoding the packet should be
107
 *    aborted in its entirety.
108
 *  - <0 - The encoder ran out of space and returned the number of bytes as a negative
109
 *    integer that would be required to encode the attribute.
110
 *  - >0 - The number of bytes written to out.
111
 */
112
typedef ssize_t (*fr_pair_encode_t)(fr_dbuff_t *out, fr_dcursor_t *cursor, void *encode_ctx);
113
114
/** A generic interface for decoding fr_pair_ts
115
 *
116
 * A decoding function should decode a single top level fr_pair_t from wire format.
117
 * If this top level fr_pair_t is a TLV, multiple child attributes may also be decoded.
118
 *
119
 * @param[in] ctx   to allocate new pairs in.
120
 * @param[in] out   to insert new pairs into.
121
 * @param[in] parent    to use for decoding
122
 * @param[in] data    to decode.
123
 * @param[in] data_len    The length of the incoming data.
124
 * @param[in] decode_ctx  Any decode specific data such as secrets or temporary allocation contexts
125
 * @return
126
 *  - <= 0 on error.  May be the offset (as a negative value) where the error occurred.
127
 *  - > 0 on success.  How many bytes were decoded.
128
 */
129
typedef ssize_t (*fr_pair_decode_t)(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_attr_t const *parent,
130
            uint8_t const *data, size_t data_len, void *decode_ctx);