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.h"
45 #include "accommon.h"
46 
47 
48 /*******************************************************************************
49  *
50  * The functions in this module satisfy the need for 64-bit string-to-integer
51  * conversions on both 32-bit and 64-bit platforms.
52  *
53  ******************************************************************************/
54 
55 #define _COMPONENT          ACPI_UTILITIES
56         ACPI_MODULE_NAME    ("utstrtoul64")
57 
58 /* Local prototypes */
59 
60 static UINT64
61 AcpiUtStrtoulBase10 (
62     char                    *String,
63     UINT32                  Flags);
64 
65 static UINT64
66 AcpiUtStrtoulBase16 (
67     char                    *String,
68     UINT32                  Flags);
69 
70 
71 /*******************************************************************************
72  *
73  * String conversion rules as written in the ACPI specification. The error
74  * conditions and behavior are different depending on the type of conversion.
75  *
76  *
77  * Implicit data type conversion: string-to-integer
78  * --------------------------------------------------
79  *
80  * Base is always 16. This is the ACPI_STRTOUL_BASE16 case.
81  *
82  * Example:
83  *      Add ("BA98", Arg0, Local0)
84  *
85  * The integer is initialized to the value zero.
86  * The ASCII string is interpreted as a hexadecimal constant.
87  *
88  *  1)  A "0x" prefix is not allowed. However, ACPICA allows this for
89  *      compatibility with previous ACPICA. (NO ERROR)
90  *
91  *  2)  Terminates when the size of an integer is reached (32 or 64 bits).
92  *      (NO ERROR)
93  *
94  *  3)  The first non-hex character terminates the conversion without error.
95  *      (NO ERROR)
96  *
97  *  4)  Conversion of a null (zero-length) string to an integer is not
98  *      allowed. However, ACPICA allows this for compatibility with previous
99  *      ACPICA. This conversion returns the value 0. (NO ERROR)
100  *
101  *
102  * Explicit data type conversion:  ToInteger() with string operand
103  * ---------------------------------------------------------------
104  *
105  * Base is either 10 (default) or 16 (with 0x prefix)
106  *
107  * Examples:
108  *      ToInteger ("1000")
109  *      ToInteger ("0xABCD")
110  *
111  *  1)  Can be (must be) either a decimal or hexadecimal numeric string.
112  *      A hex value must be prefixed by "0x" or it is interpreted as a decimal.
113  *
114  *  2)  The value must not exceed the maximum of an integer value. ACPI spec
115  *      states the behavior is "unpredictable", so ACPICA matches the behavior
116  *      of the implicit conversion case.(NO ERROR)
117  *
118  *  3)  Behavior on the first non-hex character is not specified by the ACPI
119  *      spec, so ACPICA matches the behavior of the implicit conversion case
120  *      and terminates. (NO ERROR)
121  *
122  *  4)  A null (zero-length) string is illegal.
123  *      However, ACPICA allows this for compatibility with previous ACPICA.
124  *      This conversion returns the value 0. (NO ERROR)
125  *
126  ******************************************************************************/
127 
128 
129 /*******************************************************************************
130  *
131  * FUNCTION:    AcpiUtStrtoul64
132  *
133  * PARAMETERS:  String                  - Null terminated input string
134  *              Flags                   - Conversion info, see below
135  *              ReturnValue             - Where the converted integer is
136  *                                        returned
137  *
138  * RETURN:      Status and Converted value
139  *
140  * DESCRIPTION: Convert a string into an unsigned value. Performs either a
141  *              32-bit or 64-bit conversion, depending on the input integer
142  *              size in Flags (often the current mode of the interpreter).
143  *
144  * Values for Flags:
145  *      ACPI_STRTOUL_32BIT      - Max integer value is 32 bits
146  *      ACPI_STRTOUL_64BIT      - Max integer value is 64 bits
147  *      ACPI_STRTOUL_BASE16     - Input string is hexadecimal. Default
148  *                                is 10/16 based on string prefix (0x).
149  *
150  * NOTES:
151  *   Negative numbers are not supported, as they are not supported by ACPI.
152  *
153  *   Supports only base 16 or base 10 strings/values. Does not
154  *   support Octal strings, as these are not supported by ACPI.
155  *
156  * Current users of this support:
157  *
158  *  Interpreter - Implicit and explicit conversions, GPE method names
159  *  Debugger    - Command line input string conversion
160  *  iASL        - Main parser, conversion of constants to integers
161  *  iASL        - Data Table Compiler parser (constant math expressions)
162  *  iASL        - Preprocessor (constant math expressions)
163  *  AcpiDump    - Input table addresses
164  *  AcpiExec    - Testing of the AcpiUtStrtoul64 function
165  *
166  * Note concerning callers:
167  *   AcpiGbl_IntegerByteWidth can be used to set the 32/64 limit. If used,
168  *   this global should be set to the proper width. For the core ACPICA code,
169  *   this width depends on the DSDT version. For iASL, the default byte
170  *   width is always 8 for the parser, but error checking is performed later
171  *   to flag cases where a 64-bit constant is defined in a 32-bit DSDT/SSDT.
172  *
173  ******************************************************************************/
174 
175 ACPI_STATUS
176 AcpiUtStrtoul64 (
177     char                    *String,
178     UINT32                  Flags,
179     UINT64                  *ReturnValue)
180 {
181     ACPI_STATUS             Status = AE_OK;
182     UINT32                  Base;
183 
184 
185     ACPI_FUNCTION_TRACE_STR (UtStrtoul64, String);
186 
187 
188     /* Parameter validation */
189 
190     if (!String || !ReturnValue)
191     {
192         return_ACPI_STATUS (AE_BAD_PARAMETER);
193     }
194 
195     *ReturnValue = 0;
196 
197     /* Check for zero-length string, returns 0 */
198 
199     if (*String == 0)
200     {
201         return_ACPI_STATUS (AE_OK);
202     }
203 
204     /* Skip over any white space at start of string */
205 
206     while (isspace ((int) *String))
207     {
208         String++;
209     }
210 
211     /* End of string? return 0 */
212 
213     if (*String == 0)
214     {
215         return_ACPI_STATUS (AE_OK);
216     }
217 
218     /*
219      * 1) The "0x" prefix indicates base 16. Per the ACPI specification,
220      * the "0x" prefix is only allowed for implicit (non-strict) conversions.
221      * However, we always allow it for compatibility with older ACPICA.
222      */
223     if ((*String == ACPI_ASCII_ZERO) &&
224         (tolower ((int) *(String + 1)) == 'x'))
225     {
226         String += 2;    /* Go past the 0x */
227         if (*String == 0)
228         {
229             return_ACPI_STATUS (AE_OK);     /* Return value 0 */
230         }
231 
232         Base = 16;
233     }
234 
235     /* 2) Force to base 16 (implicit conversion case) */
236 
237     else if (Flags & ACPI_STRTOUL_BASE16)
238     {
239         Base = 16;
240     }
241 
242     /* 3) Default fallback is to Base 10 */
243 
244     else
245     {
246         Base = 10;
247     }
248 
249     /* Skip all leading zeros */
250 
251     while (*String == ACPI_ASCII_ZERO)
252     {
253         String++;
254         if (*String == 0)
255         {
256             return_ACPI_STATUS (AE_OK);     /* Return value 0 */
257         }
258     }
259 
260     /* Perform the base 16 or 10 conversion */
261 
262     if (Base == 16)
263     {
264         *ReturnValue = AcpiUtStrtoulBase16 (String, Flags);
265     }
266     else
267     {
268         *ReturnValue = AcpiUtStrtoulBase10 (String, Flags);
269     }
270 
271     return_ACPI_STATUS (Status);
272 }
273 
274 
275 /*******************************************************************************
276  *
277  * FUNCTION:    AcpiUtStrtoulBase10
278  *
279  * PARAMETERS:  String                  - Null terminated input string
280  *              Flags                   - Conversion info
281  *
282  * RETURN:      64-bit converted integer
283  *
284  * DESCRIPTION: Performs a base 10 conversion of the input string to an
285  *              integer value, either 32 or 64 bits.
286  *              Note: String must be valid and non-null.
287  *
288  ******************************************************************************/
289 
290 static UINT64
291 AcpiUtStrtoulBase10 (
292     char                    *String,
293     UINT32                  Flags)
294 {
295     int                     AsciiDigit;
296     UINT64                  NextValue;
297     UINT64                  ReturnValue = 0;
298 
299 
300     /* Main loop: convert each ASCII byte in the input string */
301 
302     while (*String)
303     {
304         AsciiDigit = *String;
305         if (!isdigit (AsciiDigit))
306         {
307             /* Not ASCII 0-9, terminate */
308 
309             goto Exit;
310         }
311 
312         /* Convert and insert (add) the decimal digit */
313 
314         NextValue =
315             (ReturnValue * 10) + (AsciiDigit - ACPI_ASCII_ZERO);
316 
317         /* Check for overflow (32 or 64 bit) - return current converted value */
318 
319         if (((Flags & ACPI_STRTOUL_32BIT) && (NextValue > ACPI_UINT32_MAX)) ||
320             (NextValue < ReturnValue)) /* 64-bit overflow case */
321         {
322             goto Exit;
323         }
324 
325         ReturnValue = NextValue;
326         String++;
327     }
328 
329 Exit:
330     return (ReturnValue);
331 }
332 
333 
334 /*******************************************************************************
335  *
336  * FUNCTION:    AcpiUtStrtoulBase16
337  *
338  * PARAMETERS:  String                  - Null terminated input string
339  *              Flags                   - conversion info
340  *
341  * RETURN:      64-bit converted integer
342  *
343  * DESCRIPTION: Performs a base 16 conversion of the input string to an
344  *              integer value, either 32 or 64 bits.
345  *              Note: String must be valid and non-null.
346  *
347  ******************************************************************************/
348 
349 static UINT64
350 AcpiUtStrtoulBase16 (
351     char                    *String,
352     UINT32                  Flags)
353 {
354     int                     AsciiDigit;
355     UINT32                  ValidDigits = 1;
356     UINT64                  ReturnValue = 0;
357 
358 
359     /* Main loop: convert each ASCII byte in the input string */
360 
361     while (*String)
362     {
363         /* Check for overflow (32 or 64 bit) - return current converted value */
364 
365         if ((ValidDigits > 16) ||
366             ((ValidDigits > 8) && (Flags & ACPI_STRTOUL_32BIT)))
367         {
368             goto Exit;
369         }
370 
371         AsciiDigit = *String;
372         if (!isxdigit (AsciiDigit))
373         {
374             /* Not Hex ASCII A-F, a-f, or 0-9, terminate */
375 
376             goto Exit;
377         }
378 
379         /* Convert and insert the hex digit */
380 
381         ReturnValue =
382             (ReturnValue << 4) | AcpiUtAsciiCharToHex (AsciiDigit);
383 
384         String++;
385         ValidDigits++;
386     }
387 
388 Exit:
389     return (ReturnValue);
390 }
391