Coverage Report

Created: 2025-12-31 06:20

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/samba/lib/util/smb_strtox.c
Line
Count
Source
1
/*
2
 * Unix SMB/CIFS implementation.
3
 *
4
 * Copyright (C) Swen Schillig 2019
5
 *
6
 *   ** NOTE! The following LGPL license applies to this file.
7
 *   ** This does NOT imply that all of Samba is released
8
 *   ** under the LGPL
9
 *
10
 * This library is free software; you can redistribute it and/or
11
 * modify it under the terms of the GNU Lesser General Public
12
 * License as published by the Free Software Foundation; either
13
 * version 3 of the License, or (at your option) any later version.
14
 *
15
 * This library is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 * Lesser General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU Lesser General Public
21
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22
*/
23
24
#include "replace.h"
25
#include "smb_strtox.h"
26
27
/**
28
 * Convert a string to an unsigned long integer
29
 *
30
 * @param nptr    pointer to string which is to be converted
31
 * @param endptr  [optional] reference to remainder of the string
32
 * @param base    base of the numbering scheme
33
 * @param err   error occurred during conversion
34
 * @flags   controlling conversion feature
35
 * @result    result of the conversion as provided by strtoul
36
 *
37
 * The following flags are supported
38
 *  SMB_STR_STANDARD # raise error if negative or non-numeric
39
 *  SMB_STR_ALLOW_NEGATIVE # allow strings with a leading "-"
40
 *  SMB_STR_FULL_STR_CONV # entire string must be converted
41
 *  SMB_STR_ALLOW_NO_CONVERSION # allow empty strings or non-numeric
42
 *  SMB_STR_GLIBC_STANDARD # act exactly as the standard glibc strtoul
43
 *
44
 * The following errors are detected
45
 * - wrong base
46
 * - value overflow
47
 * - string with a leading "-" indicating a negative number
48
 * - no conversion due to empty string or not representing a number
49
 */
50
unsigned long int
51
smb_strtoul(const char *nptr, char **endptr, int base, int *err, int flags)
52
166k
{
53
166k
  unsigned long int val;
54
166k
  int saved_errno = errno;
55
166k
  char *needle = NULL;
56
166k
  char *tmp_endptr = NULL;
57
58
166k
  errno = 0;
59
166k
  *err = 0;
60
61
166k
  val = strtoul(nptr, &tmp_endptr, base);
62
63
166k
  if (endptr != NULL) {
64
166k
    *endptr = tmp_endptr;
65
166k
  }
66
67
166k
  if (errno != 0) {
68
455
    *err = errno;
69
455
    errno = saved_errno;
70
455
    return val;
71
455
  }
72
73
166k
  if ((flags & SMB_STR_ALLOW_NO_CONVERSION) == 0) {
74
    /* got an invalid number-string resulting in no conversion */
75
166k
    if (nptr == tmp_endptr) {
76
0
      *err = EINVAL;
77
0
      goto out;
78
0
    }
79
166k
  }
80
81
166k
  if ((flags & SMB_STR_ALLOW_NEGATIVE ) == 0) {
82
    /* did we convert a negative "number" ? */
83
166k
    needle = strchr(nptr, '-');
84
166k
    if (needle != NULL && needle < tmp_endptr) {
85
0
      *err = EINVAL;
86
0
      goto out;
87
0
    }
88
166k
  }
89
90
166k
  if ((flags & SMB_STR_FULL_STR_CONV) != 0) {
91
    /* did we convert the entire string ? */
92
0
    if (tmp_endptr[0] != '\0') {
93
0
      *err = EINVAL;
94
0
      goto out;
95
0
    }
96
0
  }
97
98
166k
out:
99
166k
  errno = saved_errno;
100
166k
  return val;
101
166k
}
102
103
/**
104
 * Convert a string to an unsigned long long integer
105
 *
106
 * @param nptr    pointer to string which is to be converted
107
 * @param endptr  [optional] reference to remainder of the string
108
 * @param base    base of the numbering scheme
109
 * @param err   error occurred during conversion
110
 * @flags   controlling conversion feature
111
 * @result    result of the conversion as provided by strtoull
112
 *
113
 * The following flags are supported
114
 *  SMB_STR_STANDARD # raise error if negative or non-numeric
115
 *  SMB_STR_ALLOW_NEGATIVE # allow strings with a leading "-"
116
 *  SMB_STR_FULL_STR_CONV # entire string must be converted
117
 *  SMB_STR_ALLOW_NO_CONVERSION # allow empty strings or non-numeric
118
 *  SMB_STR_GLIBC_STANDARD # act exactly as the standard glibc strtoul
119
 *
120
 * The following errors are detected
121
 * - wrong base
122
 * - value overflow
123
 * - string with a leading "-" indicating a negative number
124
 * - no conversion due to empty string or not representing a number
125
 */
126
unsigned long long int
127
smb_strtoull(const char *nptr, char **endptr, int base, int *err, int flags)
128
573k
{
129
573k
  unsigned long long int val;
130
573k
  int saved_errno = errno;
131
573k
  char *needle = NULL;
132
573k
  char *tmp_endptr = NULL;
133
134
573k
  errno = 0;
135
573k
  *err = 0;
136
137
573k
  val = strtoull(nptr, &tmp_endptr, base);
138
139
573k
  if (endptr != NULL) {
140
573k
    *endptr = tmp_endptr;
141
573k
  }
142
143
573k
  if (errno != 0) {
144
595
    *err = errno;
145
595
    errno = saved_errno;
146
595
    return val;
147
595
  }
148
149
573k
  if ((flags & SMB_STR_ALLOW_NO_CONVERSION) == 0) {
150
    /* got an invalid number-string resulting in no conversion */
151
573k
    if (nptr == tmp_endptr) {
152
134k
      *err = EINVAL;
153
134k
      goto out;
154
134k
    }
155
573k
  }
156
157
438k
  if ((flags & SMB_STR_ALLOW_NEGATIVE ) == 0) {
158
    /* did we convert a negative "number" ? */
159
438k
    needle = strchr(nptr, '-');
160
438k
    if (needle != NULL && needle < tmp_endptr) {
161
3
      *err = EINVAL;
162
3
      goto out;
163
3
    }
164
438k
  }
165
166
438k
  if ((flags & SMB_STR_FULL_STR_CONV) != 0) {
167
    /* did we convert the entire string ? */
168
0
    if (tmp_endptr[0] != '\0') {
169
0
      *err = EINVAL;
170
0
      goto out;
171
0
    }
172
0
  }
173
174
573k
out:
175
  errno = saved_errno;
176
573k
  return val;
177
438k
}