Home | History | Annotate | Line # | Download | only in isc
      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
     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
     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
     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