Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 0260034 in mainline


Ignore:
Timestamp:
2019-05-27T16:17:33Z (20 months ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master
Children:
dd0502ae
Parents:
31a566b
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2019-05-27 15:44:21)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2019-05-27 16:17:33)
Message:

Fix and test additional corner cases in strtol()

Location:
uspace/lib/c
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/strtol.c

    r31a566b r0260034  
    7777
    7878        if (nptr[1] == 'x' || nptr[1] == 'X') {
    79                 *nptrptr += 2;
    80                 return 16;
     79                if (_digit_value(nptr[2]) < 16) {
     80                        *nptrptr += 2;
     81                        return 16;
     82                }
    8183        }
    8284
     
    8587                case 'b':
    8688                case 'B':
    87                         *nptrptr += 2;
    88                         return 2;
     89                        if (_digit_value(nptr[2]) < 2) {
     90                                *nptrptr += 2;
     91                                return 2;
     92                        }
     93                        break;
    8994                case 'o':
    9095                case 'O':
    91                         *nptrptr += 2;
    92                         return 8;
     96                        if (_digit_value(nptr[2]) < 8) {
     97                                *nptrptr += 2;
     98                                return 8;
     99                        }
     100                        break;
    93101                case 'd':
    94102                case 'D':
    95103                case 't':
    96104                case 'T':
    97                         *nptrptr += 2;
    98                         return 10;
     105                        if (_digit_value(nptr[2]) < 10) {
     106                                *nptrptr += 2;
     107                                return 10;
     108                        }
     109                        break;
    99110                }
    100111        }
     
    109120        assert(nptr != NULL);
    110121        assert(sgn != NULL);
     122
     123        const char *first = nptr;
    111124
    112125        /* Skip leading whitespace. */
     
    138151                 * present when base is explicitly set to 16.
    139152                 * Our nonstandard str_* functions don't allow it.
     153                 * I don't know if that is intended, just matching the original
     154                 * functionality here.
    140155                 */
    141156
    142                 if (nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X'))
     157                if (nptr[0] == '0' && (nptr[1] == 'x' || nptr[1] == 'X') &&
     158                    _digit_value(nptr[2]) < base)
    143159                        nptr += 2;
    144160        }
     
    149165        }
    150166
    151         /* Read the value. */
     167        /* Must be at least one digit. */
     168
     169        if (_digit_value(*nptr) >= base) {
     170                /* No digits on input. */
     171                if (endptr != NULL)
     172                        *endptr = (char *) first;
     173                return 0;
     174        }
     175
     176        /* Read the value.  */
    152177
    153178        uintmax_t result = 0;
  • uspace/lib/c/test/strtol.c

    r31a566b r0260034  
    404404        endp = endp_unchanged;
    405405        errno = errno_unchanged;
     406        output = strtol(input = "    0xg", &endp, base = 0);
     407        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     408        PCUT_ASSERT_PTR_EQUALS(input + 5, endp);
     409        PCUT_ASSERT_INT_EQUALS(0, output);
     410
     411        endp = endp_unchanged;
     412        errno = errno_unchanged;
    406413        output = strtol(input = "    0x1", &endp, base = 0);
    407414        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     
    418425        endp = endp_unchanged;
    419426        errno = errno_unchanged;
     427        output = strtol(input = "    0xg", &endp, base = 16);
     428        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     429        PCUT_ASSERT_PTR_EQUALS(input + 5, endp);
     430        PCUT_ASSERT_INT_EQUALS(0, output);
     431
     432        endp = endp_unchanged;
     433        errno = errno_unchanged;
     434        output = strtol(input = "    g", &endp, base = 16);
     435        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     436        PCUT_ASSERT_PTR_EQUALS(input, endp);
     437        PCUT_ASSERT_INT_EQUALS(0, output);
     438
     439        endp = endp_unchanged;
     440        errno = errno_unchanged;
    420441        output = strtol(input = "    0x1", &endp, base = 16);
    421442        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
    422443        PCUT_ASSERT_PTR_EQUALS(input + 7, endp);
    423444        PCUT_ASSERT_INT_EQUALS(1, output);
     445
     446        endp = endp_unchanged;
     447        errno = errno_unchanged;
     448        output = strtol(input = "    +", &endp, base = 0);
     449        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     450        PCUT_ASSERT_PTR_EQUALS(input, endp);
     451        PCUT_ASSERT_INT_EQUALS(0, output);
     452
     453        endp = endp_unchanged;
     454        errno = errno_unchanged;
     455        output = strtol(input = "    -", &endp, base = 0);
     456        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     457        PCUT_ASSERT_PTR_EQUALS(input, endp);
     458        PCUT_ASSERT_INT_EQUALS(0, output);
     459
     460        endp = endp_unchanged;
     461        errno = errno_unchanged;
     462        output = strtol(input = "    +", &endp, base = 10);
     463        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     464        PCUT_ASSERT_PTR_EQUALS(input, endp);
     465        PCUT_ASSERT_INT_EQUALS(0, output);
     466
     467        endp = endp_unchanged;
     468        errno = errno_unchanged;
     469        output = strtol(input = "    -", &endp, base = 10);
     470        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     471        PCUT_ASSERT_PTR_EQUALS(input, endp);
     472        PCUT_ASSERT_INT_EQUALS(0, output);
     473
     474        endp = endp_unchanged;
     475        errno = errno_unchanged;
     476        output = strtol(input = "+", &endp, base = 0);
     477        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     478        PCUT_ASSERT_PTR_EQUALS(input, endp);
     479        PCUT_ASSERT_INT_EQUALS(0, output);
     480
     481        endp = endp_unchanged;
     482        errno = errno_unchanged;
     483        output = strtol(input = "-", &endp, base = 0);
     484        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     485        PCUT_ASSERT_PTR_EQUALS(input, endp);
     486        PCUT_ASSERT_INT_EQUALS(0, output);
     487
     488        endp = endp_unchanged;
     489        errno = errno_unchanged;
     490        output = strtol(input = "+", &endp, base = 10);
     491        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     492        PCUT_ASSERT_PTR_EQUALS(input, endp);
     493        PCUT_ASSERT_INT_EQUALS(0, output);
     494
     495        endp = endp_unchanged;
     496        errno = errno_unchanged;
     497        output = strtol(input = "-", &endp, base = 10);
     498        PCUT_ASSERT_INT_EQUALS(errno_unchanged, errno);
     499        PCUT_ASSERT_PTR_EQUALS(input, endp);
     500        PCUT_ASSERT_INT_EQUALS(0, output);
    424501}
    425502
Note: See TracChangeset for help on using the changeset viewer.