LCOV - code coverage report
Current view: top level - lib/util - smb_strtox.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 57 60 95.0 %
Date: 2024-04-21 15:09:00 Functions: 2 2 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Unix SMB/CIFS implementation.
       3             :  *
       4             :  * Copyright (C) Swen Schillig 2019
       5             :  *
       6             :  *   ** NOTE! The following LGPL license applies to this file.
       7             :  *   ** This does NOT imply that all of Samba is released
       8             :  *   ** under the LGPL
       9             :  *
      10             :  * This library is free software; you can redistribute it and/or
      11             :  * modify it under the terms of the GNU Lesser General Public
      12             :  * License as published by the Free Software Foundation; either
      13             :  * version 3 of the License, or (at your option) any later version.
      14             :  *
      15             :  * This library is distributed in the hope that it will be useful,
      16             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      18             :  * Lesser General Public License for more details.
      19             :  *
      20             :  * You should have received a copy of the GNU Lesser General Public
      21             :  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "replace.h"
      25             : #include "smb_strtox.h"
      26             : 
      27             : /**
      28             :  * Convert a string to an unsigned long integer
      29             :  *
      30             :  * @param nptr          pointer to string which is to be converted
      31             :  * @param endptr        [optional] reference to remainder of the string
      32             :  * @param base          base of the numbering scheme
      33             :  * @param err           error occurred during conversion
      34             :  * @flags               controlling conversion feature
      35             :  * @result              result of the conversion as provided by strtoul
      36             :  *
      37             :  * The following flags are supported
      38             :  *      SMB_STR_STANDARD # raise error if negative or non-numeric
      39             :  *      SMB_STR_ALLOW_NEGATIVE # allow strings with a leading "-"
      40             :  *      SMB_STR_FULL_STR_CONV # entire string must be converted
      41             :  *      SMB_STR_ALLOW_NO_CONVERSION # allow empty strings or non-numeric
      42             :  *      SMB_STR_GLIBC_STANDARD # act exactly as the standard glibc strtoul
      43             :  *
      44             :  * The following errors are detected
      45             :  * - wrong base
      46             :  * - value overflow
      47             :  * - string with a leading "-" indicating a negative number
      48             :  * - no conversion due to empty string or not representing a number
      49             :  */
      50             : unsigned long int
      51   720302533 : smb_strtoul(const char *nptr, char **endptr, int base, int *err, int flags)
      52             : {
      53     9404272 :         unsigned long int val;
      54   720302533 :         int saved_errno = errno;
      55   720302533 :         char *needle = NULL;
      56   720302533 :         char *tmp_endptr = NULL;
      57             : 
      58   720302533 :         errno = 0;
      59   720302533 :         *err = 0;
      60             : 
      61   720302533 :         val = strtoul(nptr, &tmp_endptr, base);
      62             : 
      63   720302533 :         if (endptr != NULL) {
      64   619969598 :                 *endptr = tmp_endptr;
      65             :         }
      66             : 
      67   720302533 :         if (errno != 0) {
      68           0 :                 *err = errno;
      69           0 :                 errno = saved_errno;
      70           0 :                 return val;
      71             :         }
      72             : 
      73   720302533 :         if ((flags & SMB_STR_ALLOW_NO_CONVERSION) == 0) {
      74             :                 /* got an invalid number-string resulting in no conversion */
      75   720302531 :                 if (nptr == tmp_endptr) {
      76         452 :                         *err = EINVAL;
      77         452 :                         goto out;
      78             :                 }
      79             :         }
      80             : 
      81   720302081 :         if ((flags & SMB_STR_ALLOW_NEGATIVE ) == 0) {
      82             :                 /* did we convert a negative "number" ? */
      83   720302079 :                 needle = strchr(nptr, '-');
      84   720302079 :                 if (needle != NULL && needle < tmp_endptr) {
      85           3 :                         *err = EINVAL;
      86           3 :                         goto out;
      87             :                 }
      88             :         }
      89             : 
      90   720302078 :         if ((flags & SMB_STR_FULL_STR_CONV) != 0) {
      91             :                 /* did we convert the entire string ? */
      92      880864 :                 if (tmp_endptr[0] != '\0') {
      93           6 :                         *err = EINVAL;
      94           6 :                         goto out;
      95             :                 }
      96             :         }
      97             : 
      98   720302072 : out:
      99   720302533 :         errno = saved_errno;
     100   720302533 :         return val;
     101             : }
     102             : 
     103             : /**
     104             :  * Convert a string to an unsigned long long integer
     105             :  *
     106             :  * @param nptr          pointer to string which is to be converted
     107             :  * @param endptr        [optional] reference to remainder of the string
     108             :  * @param base          base of the numbering scheme
     109             :  * @param err           error occurred during conversion
     110             :  * @flags               controlling conversion feature
     111             :  * @result              result of the conversion as provided by strtoull
     112             :  *
     113             :  * The following flags are supported
     114             :  *      SMB_STR_STANDARD # raise error if negative or non-numeric
     115             :  *      SMB_STR_ALLOW_NEGATIVE # allow strings with a leading "-"
     116             :  *      SMB_STR_FULL_STR_CONV # entire string must be converted
     117             :  *      SMB_STR_ALLOW_NO_CONVERSION # allow empty strings or non-numeric
     118             :  *      SMB_STR_GLIBC_STANDARD # act exactly as the standard glibc strtoul
     119             :  *
     120             :  * The following errors are detected
     121             :  * - wrong base
     122             :  * - value overflow
     123             :  * - string with a leading "-" indicating a negative number
     124             :  * - no conversion due to empty string or not representing a number
     125             :  */
     126             : unsigned long long int
     127   111276083 : smb_strtoull(const char *nptr, char **endptr, int base, int *err, int flags)
     128             : {
     129     3105970 :         unsigned long long int val;
     130   111276083 :         int saved_errno = errno;
     131   111276083 :         char *needle = NULL;
     132   111276083 :         char *tmp_endptr = NULL;
     133             : 
     134   111276083 :         errno = 0;
     135   111276083 :         *err = 0;
     136             : 
     137   111276083 :         val = strtoull(nptr, &tmp_endptr, base);
     138             : 
     139   111276083 :         if (endptr != NULL) {
     140   109410756 :                 *endptr = tmp_endptr;
     141             :         }
     142             : 
     143   111276083 :         if (errno != 0) {
     144          44 :                 *err = errno;
     145          44 :                 errno = saved_errno;
     146          44 :                 return val;
     147             :         }
     148             : 
     149   111276039 :         if ((flags & SMB_STR_ALLOW_NO_CONVERSION) == 0) {
     150             :                 /* got an invalid number-string resulting in no conversion */
     151   111176781 :                 if (nptr == tmp_endptr) {
     152     6114768 :                         *err = EINVAL;
     153     6114768 :                         goto out;
     154             :                 }
     155             :         }
     156             : 
     157   105161271 :         if ((flags & SMB_STR_ALLOW_NEGATIVE ) == 0) {
     158             :                 /* did we convert a negative "number" ? */
     159   105161269 :                 needle = strchr(nptr, '-');
     160   105161269 :                 if (needle != NULL && needle < tmp_endptr) {
     161           4 :                         *err = EINVAL;
     162           4 :                         goto out;
     163             :                 }
     164             :         }
     165             : 
     166   105161267 :         if ((flags & SMB_STR_FULL_STR_CONV) != 0) {
     167             :                 /* did we convert the entire string ? */
     168        2378 :                 if (tmp_endptr[0] != '\0') {
     169           4 :                         *err = EINVAL;
     170           4 :                         goto out;
     171             :                 }
     172             :         }
     173             : 
     174   105161263 : out:
     175   111276039 :         errno = saved_errno;
     176   111276039 :         return val;
     177             : }

Generated by: LCOV version 1.14