xref: /netbsd-src/external/mpl/dhcp/bind/dist/lib/isc/parseint.c (revision 4afad4b7fa6d4a0d3dedf41d1587a7250710ae54)
1 /*	$NetBSD: parseint.c,v 1.1 2024/02/18 20:57:49 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * SPDX-License-Identifier: MPL-2.0
7  *
8  * This Source Code Form is subject to the terms of the Mozilla Public
9  * License, v. 2.0. If a copy of the MPL was not distributed with this
10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
11  *
12  * See the COPYRIGHT file distributed with this work for additional
13  * information regarding copyright ownership.
14  */
15 
16 /*! \file */
17 
18 #include <ctype.h>
19 #include <errno.h>
20 #include <inttypes.h>
21 #include <limits.h>
22 #include <stdlib.h>
23 
24 #include <isc/parseint.h>
25 #include <isc/result.h>
26 
27 isc_result_t
isc_parse_uint32(uint32_t * uip,const char * string,int base)28 isc_parse_uint32(uint32_t *uip, const char *string, int base) {
29 	unsigned long n;
30 	uint32_t r;
31 	char *e;
32 	if (!isalnum((unsigned char)(string[0]))) {
33 		return (ISC_R_BADNUMBER);
34 	}
35 	errno = 0;
36 	n = strtoul(string, &e, base);
37 	if (*e != '\0') {
38 		return (ISC_R_BADNUMBER);
39 	}
40 	/*
41 	 * Where long is 64 bits we need to convert to 32 bits then test for
42 	 * equality.  This is a no-op on 32 bit machines and a good compiler
43 	 * will optimise it away.
44 	 */
45 	r = (uint32_t)n;
46 	if ((n == ULONG_MAX && errno == ERANGE) || (n != (unsigned long)r)) {
47 		return (ISC_R_RANGE);
48 	}
49 	*uip = r;
50 	return (ISC_R_SUCCESS);
51 }
52 
53 isc_result_t
isc_parse_uint16(uint16_t * uip,const char * string,int base)54 isc_parse_uint16(uint16_t *uip, const char *string, int base) {
55 	uint32_t val;
56 	isc_result_t result;
57 	result = isc_parse_uint32(&val, string, base);
58 	if (result != ISC_R_SUCCESS) {
59 		return (result);
60 	}
61 	if (val > 0xFFFF) {
62 		return (ISC_R_RANGE);
63 	}
64 	*uip = (uint16_t)val;
65 	return (ISC_R_SUCCESS);
66 }
67 
68 isc_result_t
isc_parse_uint8(uint8_t * uip,const char * string,int base)69 isc_parse_uint8(uint8_t *uip, const char *string, int base) {
70 	uint32_t val;
71 	isc_result_t result;
72 	result = isc_parse_uint32(&val, string, base);
73 	if (result != ISC_R_SUCCESS) {
74 		return (result);
75 	}
76 	if (val > 0xFF) {
77 		return (ISC_R_RANGE);
78 	}
79 	*uip = (uint8_t)val;
80 	return (ISC_R_SUCCESS);
81 }
82