1 /******************************************************************************* 2 * 3 * Module Name: utstrsuppt - Support functions for string-to-integer conversion 4 * 5 ******************************************************************************/ 6 7 /****************************************************************************** 8 * 9 * 1. Copyright Notice 10 * 11 * Some or all of this work - Copyright (c) 1999 - 2020, Intel Corp. 12 * All rights reserved. 13 * 14 * 2. License 15 * 16 * 2.1. This is your license from Intel Corp. under its intellectual property 17 * rights. You may have additional license terms from the party that provided 18 * you this software, covering your right to use that party's intellectual 19 * property rights. 20 * 21 * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a 22 * copy of the source code appearing in this file ("Covered Code") an 23 * irrevocable, perpetual, worldwide license under Intel's copyrights in the 24 * base code distributed originally by Intel ("Original Intel Code") to copy, 25 * make derivatives, distribute, use and display any portion of the Covered 26 * Code in any form, with the right to sublicense such rights; and 27 * 28 * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent 29 * license (with the right to sublicense), under only those claims of Intel 30 * patents that are infringed by the Original Intel Code, to make, use, sell, 31 * offer to sell, and import the Covered Code and derivative works thereof 32 * solely to the minimum extent necessary to exercise the above copyright 33 * license, and in no event shall the patent license extend to any additions 34 * to or modifications of the Original Intel Code. No other license or right 35 * is granted directly or by implication, estoppel or otherwise; 36 * 37 * The above copyright and patent license is granted only if the following 38 * conditions are met: 39 * 40 * 3. Conditions 41 * 42 * 3.1. Redistribution of Source with Rights to Further Distribute Source. 43 * Redistribution of source code of any substantial portion of the Covered 44 * Code or modification with rights to further distribute source must include 45 * the above Copyright Notice, the above License, this list of Conditions, 46 * and the following Disclaimer and Export Compliance provision. In addition, 47 * Licensee must cause all Covered Code to which Licensee contributes to 48 * contain a file documenting the changes Licensee made to create that Covered 49 * Code and the date of any change. Licensee must include in that file the 50 * documentation of any changes made by any predecessor Licensee. Licensee 51 * must include a prominent statement that the modification is derived, 52 * directly or indirectly, from Original Intel Code. 53 * 54 * 3.2. Redistribution of Source with no Rights to Further Distribute Source. 55 * Redistribution of source code of any substantial portion of the Covered 56 * Code or modification without rights to further distribute source must 57 * include the following Disclaimer and Export Compliance provision in the 58 * documentation and/or other materials provided with distribution. In 59 * addition, Licensee may not authorize further sublicense of source of any 60 * portion of the Covered Code, and must include terms to the effect that the 61 * license from Licensee to its licensee is limited to the intellectual 62 * property embodied in the software Licensee provides to its licensee, and 63 * not to intellectual property embodied in modifications its licensee may 64 * make. 65 * 66 * 3.3. Redistribution of Executable. Redistribution in executable form of any 67 * substantial portion of the Covered Code or modification must reproduce the 68 * above Copyright Notice, and the following Disclaimer and Export Compliance 69 * provision in the documentation and/or other materials provided with the 70 * distribution. 71 * 72 * 3.4. Intel retains all right, title, and interest in and to the Original 73 * Intel Code. 74 * 75 * 3.5. Neither the name Intel nor any other trademark owned or controlled by 76 * Intel shall be used in advertising or otherwise to promote the sale, use or 77 * other dealings in products derived from or relating to the Covered Code 78 * without prior written authorization from Intel. 79 * 80 * 4. Disclaimer and Export Compliance 81 * 82 * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED 83 * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE 84 * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE, 85 * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY 86 * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY 87 * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A 88 * PARTICULAR PURPOSE. 89 * 90 * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES 91 * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR 92 * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT, 93 * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY 94 * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL 95 * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS 96 * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY 97 * LIMITED REMEDY. 98 * 99 * 4.3. Licensee shall not export, either directly or indirectly, any of this 100 * software or system incorporating such software without first obtaining any 101 * required license or other approval from the U. S. Department of Commerce or 102 * any other agency or department of the United States Government. In the 103 * event Licensee exports any such software from the United States or 104 * re-exports any such software from a foreign destination, Licensee shall 105 * ensure that the distribution and export/re-export of the software is in 106 * compliance with all laws, regulations, orders, or other restrictions of the 107 * U.S. Export Administration Regulations. Licensee agrees that neither it nor 108 * any of its subsidiaries will export/re-export any technical data, process, 109 * software, or service, directly or indirectly, to any country for which the 110 * United States government or any agency thereof requires an export license, 111 * other governmental approval, or letter of assurance, without first obtaining 112 * such license, approval or letter. 113 * 114 ***************************************************************************** 115 * 116 * Alternatively, you may choose to be licensed under the terms of the 117 * following license: 118 * 119 * Redistribution and use in source and binary forms, with or without 120 * modification, are permitted provided that the following conditions 121 * are met: 122 * 1. Redistributions of source code must retain the above copyright 123 * notice, this list of conditions, and the following disclaimer, 124 * without modification. 125 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 126 * substantially similar to the "NO WARRANTY" disclaimer below 127 * ("Disclaimer") and any redistribution must be conditioned upon 128 * including a substantially similar Disclaimer requirement for further 129 * binary redistribution. 130 * 3. Neither the names of the above-listed copyright holders nor the names 131 * of any contributors may be used to endorse or promote products derived 132 * from this software without specific prior written permission. 133 * 134 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 135 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 136 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 137 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 138 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 139 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 140 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 141 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 142 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 143 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 144 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 145 * 146 * Alternatively, you may choose to be licensed under the terms of the 147 * GNU General Public License ("GPL") version 2 as published by the Free 148 * Software Foundation. 149 * 150 *****************************************************************************/ 151 152 #include <contrib/dev/acpica/include/acpi.h> 153 #include <contrib/dev/acpica/include/accommon.h> 154 155 #define _COMPONENT ACPI_UTILITIES 156 ACPI_MODULE_NAME ("utstrsuppt") 157 158 159 /* Local prototypes */ 160 161 static ACPI_STATUS 162 AcpiUtInsertDigit ( 163 UINT64 *AccumulatedValue, 164 UINT32 Base, 165 int AsciiDigit); 166 167 static ACPI_STATUS 168 AcpiUtStrtoulMultiply64 ( 169 UINT64 Multiplicand, 170 UINT32 Base, 171 UINT64 *OutProduct); 172 173 static ACPI_STATUS 174 AcpiUtStrtoulAdd64 ( 175 UINT64 Addend1, 176 UINT32 Digit, 177 UINT64 *OutSum); 178 179 180 /******************************************************************************* 181 * 182 * FUNCTION: AcpiUtConvertOctalString 183 * 184 * PARAMETERS: String - Null terminated input string 185 * ReturnValuePtr - Where the converted value is returned 186 * 187 * RETURN: Status and 64-bit converted integer 188 * 189 * DESCRIPTION: Performs a base 8 conversion of the input string to an 190 * integer value, either 32 or 64 bits. 191 * 192 * NOTE: Maximum 64-bit unsigned octal value is 01777777777777777777777 193 * Maximum 32-bit unsigned octal value is 037777777777 194 * 195 ******************************************************************************/ 196 197 ACPI_STATUS 198 AcpiUtConvertOctalString ( 199 char *String, 200 UINT64 *ReturnValuePtr) 201 { 202 UINT64 AccumulatedValue = 0; 203 ACPI_STATUS Status = AE_OK; 204 205 206 /* Convert each ASCII byte in the input string */ 207 208 while (*String) 209 { 210 /* Character must be ASCII 0-7, otherwise terminate with no error */ 211 212 if (!(ACPI_IS_OCTAL_DIGIT (*String))) 213 { 214 break; 215 } 216 217 /* Convert and insert this octal digit into the accumulator */ 218 219 Status = AcpiUtInsertDigit (&AccumulatedValue, 8, *String); 220 if (ACPI_FAILURE (Status)) 221 { 222 Status = AE_OCTAL_OVERFLOW; 223 break; 224 } 225 226 String++; 227 } 228 229 /* Always return the value that has been accumulated */ 230 231 *ReturnValuePtr = AccumulatedValue; 232 return (Status); 233 } 234 235 236 /******************************************************************************* 237 * 238 * FUNCTION: AcpiUtConvertDecimalString 239 * 240 * PARAMETERS: String - Null terminated input string 241 * ReturnValuePtr - Where the converted value is returned 242 * 243 * RETURN: Status and 64-bit converted integer 244 * 245 * DESCRIPTION: Performs a base 10 conversion of the input string to an 246 * integer value, either 32 or 64 bits. 247 * 248 * NOTE: Maximum 64-bit unsigned decimal value is 18446744073709551615 249 * Maximum 32-bit unsigned decimal value is 4294967295 250 * 251 ******************************************************************************/ 252 253 ACPI_STATUS 254 AcpiUtConvertDecimalString ( 255 char *String, 256 UINT64 *ReturnValuePtr) 257 { 258 UINT64 AccumulatedValue = 0; 259 ACPI_STATUS Status = AE_OK; 260 261 262 /* Convert each ASCII byte in the input string */ 263 264 while (*String) 265 { 266 /* Character must be ASCII 0-9, otherwise terminate with no error */ 267 268 if (!isdigit (*String)) 269 { 270 break; 271 } 272 273 /* Convert and insert this decimal digit into the accumulator */ 274 275 Status = AcpiUtInsertDigit (&AccumulatedValue, 10, *String); 276 if (ACPI_FAILURE (Status)) 277 { 278 Status = AE_DECIMAL_OVERFLOW; 279 break; 280 } 281 282 String++; 283 } 284 285 /* Always return the value that has been accumulated */ 286 287 *ReturnValuePtr = AccumulatedValue; 288 return (Status); 289 } 290 291 292 /******************************************************************************* 293 * 294 * FUNCTION: AcpiUtConvertHexString 295 * 296 * PARAMETERS: String - Null terminated input string 297 * ReturnValuePtr - Where the converted value is returned 298 * 299 * RETURN: Status and 64-bit converted integer 300 * 301 * DESCRIPTION: Performs a base 16 conversion of the input string to an 302 * integer value, either 32 or 64 bits. 303 * 304 * NOTE: Maximum 64-bit unsigned hex value is 0xFFFFFFFFFFFFFFFF 305 * Maximum 32-bit unsigned hex value is 0xFFFFFFFF 306 * 307 ******************************************************************************/ 308 309 ACPI_STATUS 310 AcpiUtConvertHexString ( 311 char *String, 312 UINT64 *ReturnValuePtr) 313 { 314 UINT64 AccumulatedValue = 0; 315 ACPI_STATUS Status = AE_OK; 316 317 318 /* Convert each ASCII byte in the input string */ 319 320 while (*String) 321 { 322 /* Must be ASCII A-F, a-f, or 0-9, otherwise terminate with no error */ 323 324 if (!isxdigit (*String)) 325 { 326 break; 327 } 328 329 /* Convert and insert this hex digit into the accumulator */ 330 331 Status = AcpiUtInsertDigit (&AccumulatedValue, 16, *String); 332 if (ACPI_FAILURE (Status)) 333 { 334 Status = AE_HEX_OVERFLOW; 335 break; 336 } 337 338 String++; 339 } 340 341 /* Always return the value that has been accumulated */ 342 343 *ReturnValuePtr = AccumulatedValue; 344 return (Status); 345 } 346 347 348 /******************************************************************************* 349 * 350 * FUNCTION: AcpiUtRemoveLeadingZeros 351 * 352 * PARAMETERS: String - Pointer to input ASCII string 353 * 354 * RETURN: Next character after any leading zeros. This character may be 355 * used by the caller to detect end-of-string. 356 * 357 * DESCRIPTION: Remove any leading zeros in the input string. Return the 358 * next character after the final ASCII zero to enable the caller 359 * to check for the end of the string (NULL terminator). 360 * 361 ******************************************************************************/ 362 363 char 364 AcpiUtRemoveLeadingZeros ( 365 char **String) 366 { 367 368 while (**String == ACPI_ASCII_ZERO) 369 { 370 *String += 1; 371 } 372 373 return (**String); 374 } 375 376 377 /******************************************************************************* 378 * 379 * FUNCTION: AcpiUtRemoveWhitespace 380 * 381 * PARAMETERS: String - Pointer to input ASCII string 382 * 383 * RETURN: Next character after any whitespace. This character may be 384 * used by the caller to detect end-of-string. 385 * 386 * DESCRIPTION: Remove any leading whitespace in the input string. Return the 387 * next character after the final ASCII zero to enable the caller 388 * to check for the end of the string (NULL terminator). 389 * 390 ******************************************************************************/ 391 392 char 393 AcpiUtRemoveWhitespace ( 394 char **String) 395 { 396 397 while (isspace ((UINT8) **String)) 398 { 399 *String += 1; 400 } 401 402 return (**String); 403 } 404 405 406 /******************************************************************************* 407 * 408 * FUNCTION: AcpiUtDetectHexPrefix 409 * 410 * PARAMETERS: String - Pointer to input ASCII string 411 * 412 * RETURN: TRUE if a "0x" prefix was found at the start of the string 413 * 414 * DESCRIPTION: Detect and remove a hex "0x" prefix 415 * 416 ******************************************************************************/ 417 418 BOOLEAN 419 AcpiUtDetectHexPrefix ( 420 char **String) 421 { 422 char *InitialPosition = *String; 423 424 AcpiUtRemoveHexPrefix (String); 425 if (*String != InitialPosition) 426 { 427 return (TRUE); /* String is past leading 0x */ 428 } 429 430 return (FALSE); /* Not a hex string */ 431 } 432 433 434 /******************************************************************************* 435 * 436 * FUNCTION: AcpiUtRemoveHexPrefix 437 * 438 * PARAMETERS: String - Pointer to input ASCII string 439 * 440 * RETURN: none 441 * 442 * DESCRIPTION: Remove a hex "0x" prefix 443 * 444 ******************************************************************************/ 445 446 void 447 AcpiUtRemoveHexPrefix ( 448 char **String) 449 { 450 if ((**String == ACPI_ASCII_ZERO) && 451 (tolower ((int) *(*String + 1)) == 'x')) 452 { 453 *String += 2; /* Go past the leading 0x */ 454 } 455 } 456 457 458 /******************************************************************************* 459 * 460 * FUNCTION: AcpiUtDetectOctalPrefix 461 * 462 * PARAMETERS: String - Pointer to input ASCII string 463 * 464 * RETURN: True if an octal "0" prefix was found at the start of the 465 * string 466 * 467 * DESCRIPTION: Detect and remove an octal prefix (zero) 468 * 469 ******************************************************************************/ 470 471 BOOLEAN 472 AcpiUtDetectOctalPrefix ( 473 char **String) 474 { 475 476 if (**String == ACPI_ASCII_ZERO) 477 { 478 *String += 1; /* Go past the leading 0 */ 479 return (TRUE); 480 } 481 482 return (FALSE); /* Not an octal string */ 483 } 484 485 486 /******************************************************************************* 487 * 488 * FUNCTION: AcpiUtInsertDigit 489 * 490 * PARAMETERS: AccumulatedValue - Current value of the integer value 491 * accumulator. The new value is 492 * returned here. 493 * Base - Radix, either 8/10/16 494 * AsciiDigit - ASCII single digit to be inserted 495 * 496 * RETURN: Status and result of the convert/insert operation. The only 497 * possible returned exception code is numeric overflow of 498 * either the multiply or add conversion operations. 499 * 500 * DESCRIPTION: Generic conversion and insertion function for all bases: 501 * 502 * 1) Multiply the current accumulated/converted value by the 503 * base in order to make room for the new character. 504 * 505 * 2) Convert the new character to binary and add it to the 506 * current accumulated value. 507 * 508 * Note: The only possible exception indicates an integer 509 * overflow (AE_NUMERIC_OVERFLOW) 510 * 511 ******************************************************************************/ 512 513 static ACPI_STATUS 514 AcpiUtInsertDigit ( 515 UINT64 *AccumulatedValue, 516 UINT32 Base, 517 int AsciiDigit) 518 { 519 ACPI_STATUS Status; 520 UINT64 Product; 521 522 523 /* Make room in the accumulated value for the incoming digit */ 524 525 Status = AcpiUtStrtoulMultiply64 (*AccumulatedValue, Base, &Product); 526 if (ACPI_FAILURE (Status)) 527 { 528 return (Status); 529 } 530 531 /* Add in the new digit, and store the sum to the accumulated value */ 532 533 Status = AcpiUtStrtoulAdd64 (Product, AcpiUtAsciiCharToHex (AsciiDigit), 534 AccumulatedValue); 535 536 return (Status); 537 } 538 539 540 /******************************************************************************* 541 * 542 * FUNCTION: AcpiUtStrtoulMultiply64 543 * 544 * PARAMETERS: Multiplicand - Current accumulated converted integer 545 * Base - Base/Radix 546 * OutProduct - Where the product is returned 547 * 548 * RETURN: Status and 64-bit product 549 * 550 * DESCRIPTION: Multiply two 64-bit values, with checking for 64-bit overflow as 551 * well as 32-bit overflow if necessary (if the current global 552 * integer width is 32). 553 * 554 ******************************************************************************/ 555 556 static ACPI_STATUS 557 AcpiUtStrtoulMultiply64 ( 558 UINT64 Multiplicand, 559 UINT32 Base, 560 UINT64 *OutProduct) 561 { 562 UINT64 Product; 563 UINT64 Quotient; 564 565 566 /* Exit if either operand is zero */ 567 568 *OutProduct = 0; 569 if (!Multiplicand || !Base) 570 { 571 return (AE_OK); 572 } 573 574 /* 575 * Check for 64-bit overflow before the actual multiplication. 576 * 577 * Notes: 64-bit division is often not supported on 32-bit platforms 578 * (it requires a library function), Therefore ACPICA has a local 579 * 64-bit divide function. Also, Multiplier is currently only used 580 * as the radix (8/10/16), to the 64/32 divide will always work. 581 */ 582 AcpiUtShortDivide (ACPI_UINT64_MAX, Base, &Quotient, NULL); 583 if (Multiplicand > Quotient) 584 { 585 return (AE_NUMERIC_OVERFLOW); 586 } 587 588 Product = Multiplicand * Base; 589 590 /* Check for 32-bit overflow if necessary */ 591 592 if ((AcpiGbl_IntegerBitWidth == 32) && (Product > ACPI_UINT32_MAX)) 593 { 594 return (AE_NUMERIC_OVERFLOW); 595 } 596 597 *OutProduct = Product; 598 return (AE_OK); 599 } 600 601 602 /******************************************************************************* 603 * 604 * FUNCTION: AcpiUtStrtoulAdd64 605 * 606 * PARAMETERS: Addend1 - Current accumulated converted integer 607 * Digit - New hex value/char 608 * OutSum - Where sum is returned (Accumulator) 609 * 610 * RETURN: Status and 64-bit sum 611 * 612 * DESCRIPTION: Add two 64-bit values, with checking for 64-bit overflow as 613 * well as 32-bit overflow if necessary (if the current global 614 * integer width is 32). 615 * 616 ******************************************************************************/ 617 618 static ACPI_STATUS 619 AcpiUtStrtoulAdd64 ( 620 UINT64 Addend1, 621 UINT32 Digit, 622 UINT64 *OutSum) 623 { 624 UINT64 Sum; 625 626 627 /* Check for 64-bit overflow before the actual addition */ 628 629 if ((Addend1 > 0) && (Digit > (ACPI_UINT64_MAX - Addend1))) 630 { 631 return (AE_NUMERIC_OVERFLOW); 632 } 633 634 Sum = Addend1 + Digit; 635 636 /* Check for 32-bit overflow if necessary */ 637 638 if ((AcpiGbl_IntegerBitWidth == 32) && (Sum > ACPI_UINT32_MAX)) 639 { 640 return (AE_NUMERIC_OVERFLOW); 641 } 642 643 *OutSum = Sum; 644 return (AE_OK); 645 } 646