VERSION: Disable GIT_SNAPSHOT for the Samba 4.17.0rc1 release.
[Samba.git] / lib / util / smb_strtox.c
blobe57316e29b5d2d0541e9e45520fe0ffe89c5c917
1 /*
2 * Unix SMB/CIFS implementation.
4 * Copyright (C) Swen Schillig 2019
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
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.
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.
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/>.
24 #include "replace.h"
25 #include "smb_strtox.h"
27 /**
28 * Convert a string to an unsigned long integer
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 occured during conversion
34 * @flags controlling conversion feature
35 * @result result of the conversion as provided by strtoul
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
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
50 unsigned long int
51 smb_strtoul(const char *nptr, char **endptr, int base, int *err, int flags)
53 unsigned long int val;
54 int saved_errno = errno;
55 char *needle = NULL;
56 char *tmp_endptr = NULL;
58 errno = 0;
59 *err = 0;
61 val = strtoul(nptr, &tmp_endptr, base);
63 if (endptr != NULL) {
64 *endptr = tmp_endptr;
67 if (errno != 0) {
68 *err = errno;
69 errno = saved_errno;
70 return val;
73 if ((flags & SMB_STR_ALLOW_NO_CONVERSION) == 0) {
74 /* got an invalid number-string resulting in no conversion */
75 if (nptr == tmp_endptr) {
76 *err = EINVAL;
77 goto out;
81 if ((flags & SMB_STR_ALLOW_NEGATIVE ) == 0) {
82 /* did we convert a negative "number" ? */
83 needle = strchr(nptr, '-');
84 if (needle != NULL && needle < tmp_endptr) {
85 *err = EINVAL;
86 goto out;
90 if ((flags & SMB_STR_FULL_STR_CONV) != 0) {
91 /* did we convert the entire string ? */
92 if (tmp_endptr[0] != '\0') {
93 *err = EINVAL;
94 goto out;
98 out:
99 errno = saved_errno;
100 return val;
104 * Convert a string to an unsigned long long integer
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 occured during conversion
110 * @flags controlling conversion feature
111 * @result result of the conversion as provided by strtoull
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
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
126 unsigned long long int
127 smb_strtoull(const char *nptr, char **endptr, int base, int *err, int flags)
129 unsigned long long int val;
130 int saved_errno = errno;
131 char *needle = NULL;
132 char *tmp_endptr = NULL;
134 errno = 0;
135 *err = 0;
137 val = strtoull(nptr, &tmp_endptr, base);
139 if (endptr != NULL) {
140 *endptr = tmp_endptr;
143 if (errno != 0) {
144 *err = errno;
145 errno = saved_errno;
146 return val;
149 if ((flags & SMB_STR_ALLOW_NO_CONVERSION) == 0) {
150 /* got an invalid number-string resulting in no conversion */
151 if (nptr == tmp_endptr) {
152 *err = EINVAL;
153 goto out;
157 if ((flags & SMB_STR_ALLOW_NEGATIVE ) == 0) {
158 /* did we convert a negative "number" ? */
159 needle = strchr(nptr, '-');
160 if (needle != NULL && needle < tmp_endptr) {
161 *err = EINVAL;
162 goto out;
166 if ((flags & SMB_STR_FULL_STR_CONV) != 0) {
167 /* did we convert the entire string ? */
168 if (tmp_endptr[0] != '\0') {
169 *err = EINVAL;
170 goto out;
174 out:
175 errno = saved_errno;
176 return val;