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