1 /*******************************************************************************
2  *
3  * Module Name: utstrtoul64 - string to 64-bit integer support
4  *
5  ******************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2016, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include <acpi/acpi.h>
45 #include "accommon.h"
46 
47 /*******************************************************************************
48  *
49  * The functions in this module satisfy the need for 64-bit string-to-integer
50  * conversions on both 32-bit and 64-bit platforms.
51  *
52  ******************************************************************************/
53 
54 #define _COMPONENT          ACPI_UTILITIES
55 ACPI_MODULE_NAME("utstrtoul64")
56 
57 /* Local prototypes */
58 static u64 acpi_ut_strtoul_base10(char *string, u32 flags);
59 
60 static u64 acpi_ut_strtoul_base16(char *string, u32 flags);
61 
62 /*******************************************************************************
63  *
64  * String conversion rules as written in the ACPI specification. The error
65  * conditions and behavior are different depending on the type of conversion.
66  *
67  *
68  * Implicit data type conversion: string-to-integer
69  * --------------------------------------------------
70  *
71  * Base is always 16. This is the ACPI_STRTOUL_BASE16 case.
72  *
73  * Example:
74  *      Add ("BA98", Arg0, Local0)
75  *
76  * The integer is initialized to the value zero.
77  * The ASCII string is interpreted as a hexadecimal constant.
78  *
79  *  1)  A "0x" prefix is not allowed. However, ACPICA allows this for
80  *      compatibility with previous ACPICA. (NO ERROR)
81  *
82  *  2)  Terminates when the size of an integer is reached (32 or 64 bits).
83  *      (NO ERROR)
84  *
85  *  3)  The first non-hex character terminates the conversion without error.
86  *      (NO ERROR)
87  *
88  *  4)  Conversion of a null (zero-length) string to an integer is not
89  *      allowed. However, ACPICA allows this for compatibility with previous
90  *      ACPICA. This conversion returns the value 0. (NO ERROR)
91  *
92  *
93  * Explicit data type conversion:  to_integer() with string operand
94  * ---------------------------------------------------------------
95  *
96  * Base is either 10 (default) or 16 (with 0x prefix)
97  *
98  * Examples:
99  *      to_integer ("1000")
100  *      to_integer ("0xABCD")
101  *
102  *  1)  Can be (must be) either a decimal or hexadecimal numeric string.
103  *      A hex value must be prefixed by "0x" or it is interpreted as a decimal.
104  *
105  *  2)  The value must not exceed the maximum of an integer value. ACPI spec
106  *      states the behavior is "unpredictable", so ACPICA matches the behavior
107  *      of the implicit conversion case.(NO ERROR)
108  *
109  *  3)  Behavior on the first non-hex character is not specified by the ACPI
110  *      spec, so ACPICA matches the behavior of the implicit conversion case
111  *      and terminates. (NO ERROR)
112  *
113  *  4)  A null (zero-length) string is illegal.
114  *      However, ACPICA allows this for compatibility with previous ACPICA.
115  *      This conversion returns the value 0. (NO ERROR)
116  *
117  ******************************************************************************/
118 
119 /*******************************************************************************
120  *
121  * FUNCTION:    acpi_ut_strtoul64
122  *
123  * PARAMETERS:  string                  - Null terminated input string
124  *              flags                   - Conversion info, see below
125  *              return_value            - Where the converted integer is
126  *                                        returned
127  *
128  * RETURN:      Status and Converted value
129  *
130  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
131  *              32-bit or 64-bit conversion, depending on the input integer
132  *              size in Flags (often the current mode of the interpreter).
133  *
134  * Values for Flags:
135  *      ACPI_STRTOUL_32BIT      - Max integer value is 32 bits
136  *      ACPI_STRTOUL_64BIT      - Max integer value is 64 bits
137  *      ACPI_STRTOUL_BASE16     - Input string is hexadecimal. Default
138  *                                is 10/16 based on string prefix (0x).
139  *
140  * NOTES:
141  *   Negative numbers are not supported, as they are not supported by ACPI.
142  *
143  *   Supports only base 16 or base 10 strings/values. Does not
144  *   support Octal strings, as these are not supported by ACPI.
145  *
146  * Current users of this support:
147  *
148  *  interpreter - Implicit and explicit conversions, GPE method names
149  *  debugger    - Command line input string conversion
150  *  iASL        - Main parser, conversion of constants to integers
151  *  iASL        - Data Table Compiler parser (constant math expressions)
152  *  iASL        - Preprocessor (constant math expressions)
153  *  acpi_dump   - Input table addresses
154  *  acpi_exec   - Testing of the acpi_ut_strtoul64 function
155  *
156  * Note concerning callers:
157  *   acpi_gbl_integer_byte_width can be used to set the 32/64 limit. If used,
158  *   this global should be set to the proper width. For the core ACPICA code,
159  *   this width depends on the DSDT version. For iASL, the default byte
160  *   width is always 8 for the parser, but error checking is performed later
161  *   to flag cases where a 64-bit constant is defined in a 32-bit DSDT/SSDT.
162  *
163  ******************************************************************************/
164 
165 acpi_status acpi_ut_strtoul64(char *string, u32 flags, u64 *return_value)
166 {
167 	acpi_status status = AE_OK;
168 	u32 base;
169 
170 	ACPI_FUNCTION_TRACE_STR(ut_strtoul64, string);
171 
172 	/* Parameter validation */
173 
174 	if (!string || !return_value) {
175 		return_ACPI_STATUS(AE_BAD_PARAMETER);
176 	}
177 
178 	*return_value = 0;
179 
180 	/* Check for zero-length string, returns 0 */
181 
182 	if (*string == 0) {
183 		return_ACPI_STATUS(AE_OK);
184 	}
185 
186 	/* Skip over any white space at start of string */
187 
188 	while (isspace((int)*string)) {
189 		string++;
190 	}
191 
192 	/* End of string? return 0 */
193 
194 	if (*string == 0) {
195 		return_ACPI_STATUS(AE_OK);
196 	}
197 
198 	/*
199 	 * 1) The "0x" prefix indicates base 16. Per the ACPI specification,
200 	 * the "0x" prefix is only allowed for implicit (non-strict) conversions.
201 	 * However, we always allow it for compatibility with older ACPICA.
202 	 */
203 	if ((*string == ACPI_ASCII_ZERO) &&
204 	    (tolower((int)*(string + 1)) == 'x')) {
205 		string += 2;	/* Go past the 0x */
206 		if (*string == 0) {
207 			return_ACPI_STATUS(AE_OK);	/* Return value 0 */
208 		}
209 
210 		base = 16;
211 	}
212 
213 	/* 2) Force to base 16 (implicit conversion case) */
214 
215 	else if (flags & ACPI_STRTOUL_BASE16) {
216 		base = 16;
217 	}
218 
219 	/* 3) Default fallback is to Base 10 */
220 
221 	else {
222 		base = 10;
223 	}
224 
225 	/* Skip all leading zeros */
226 
227 	while (*string == ACPI_ASCII_ZERO) {
228 		string++;
229 		if (*string == 0) {
230 			return_ACPI_STATUS(AE_OK);	/* Return value 0 */
231 		}
232 	}
233 
234 	/* Perform the base 16 or 10 conversion */
235 
236 	if (base == 16) {
237 		*return_value = acpi_ut_strtoul_base16(string, flags);
238 	} else {
239 		*return_value = acpi_ut_strtoul_base10(string, flags);
240 	}
241 
242 	return_ACPI_STATUS(status);
243 }
244 
245 /*******************************************************************************
246  *
247  * FUNCTION:    acpi_ut_strtoul_base10
248  *
249  * PARAMETERS:  string                  - Null terminated input string
250  *              flags                   - Conversion info
251  *
252  * RETURN:      64-bit converted integer
253  *
254  * DESCRIPTION: Performs a base 10 conversion of the input string to an
255  *              integer value, either 32 or 64 bits.
256  *              Note: String must be valid and non-null.
257  *
258  ******************************************************************************/
259 
260 static u64 acpi_ut_strtoul_base10(char *string, u32 flags)
261 {
262 	int ascii_digit;
263 	u64 next_value;
264 	u64 return_value = 0;
265 
266 	/* Main loop: convert each ASCII byte in the input string */
267 
268 	while (*string) {
269 		ascii_digit = *string;
270 		if (!isdigit(ascii_digit)) {
271 
272 			/* Not ASCII 0-9, terminate */
273 
274 			goto exit;
275 		}
276 
277 		/* Convert and insert (add) the decimal digit */
278 
279 		next_value =
280 		    (return_value * 10) + (ascii_digit - ACPI_ASCII_ZERO);
281 
282 		/* Check for overflow (32 or 64 bit) - return current converted value */
283 
284 		if (((flags & ACPI_STRTOUL_32BIT) && (next_value > ACPI_UINT32_MAX)) || (next_value < return_value)) {	/* 64-bit overflow case */
285 			goto exit;
286 		}
287 
288 		return_value = next_value;
289 		string++;
290 	}
291 
292 exit:
293 	return (return_value);
294 }
295 
296 /*******************************************************************************
297  *
298  * FUNCTION:    acpi_ut_strtoul_base16
299  *
300  * PARAMETERS:  string                  - Null terminated input string
301  *              flags                   - conversion info
302  *
303  * RETURN:      64-bit converted integer
304  *
305  * DESCRIPTION: Performs a base 16 conversion of the input string to an
306  *              integer value, either 32 or 64 bits.
307  *              Note: String must be valid and non-null.
308  *
309  ******************************************************************************/
310 
311 static u64 acpi_ut_strtoul_base16(char *string, u32 flags)
312 {
313 	int ascii_digit;
314 	u32 valid_digits = 1;
315 	u64 return_value = 0;
316 
317 	/* Main loop: convert each ASCII byte in the input string */
318 
319 	while (*string) {
320 
321 		/* Check for overflow (32 or 64 bit) - return current converted value */
322 
323 		if ((valid_digits > 16) ||
324 		    ((valid_digits > 8) && (flags & ACPI_STRTOUL_32BIT))) {
325 			goto exit;
326 		}
327 
328 		ascii_digit = *string;
329 		if (!isxdigit(ascii_digit)) {
330 
331 			/* Not Hex ASCII A-F, a-f, or 0-9, terminate */
332 
333 			goto exit;
334 		}
335 
336 		/* Convert and insert the hex digit */
337 
338 		return_value =
339 		    (return_value << 4) |
340 		    acpi_ut_ascii_char_to_hex(ascii_digit);
341 
342 		string++;
343 		valid_digits++;
344 	}
345 
346 exit:
347 	return (return_value);
348 }
349