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