strtol(3) and wcstol(3) family wrongly update endptr when parsing "0x".

Issue #64 closed
Takehiko NOZAKI repo owner created an issue

try following code:

#include <stdlib.h>
#include <assert.h>

int
main(void)
{
        char *t;

        strtol("0x", &t, 0);
        assert(*t == 'x');
}

glibc2, Solaris works fine. but all *BSD derived strtol(3) implemetation may fail(cygwin's newlib and so on).

Comments (13)

  1. Takehiko NOZAKI reporter

    testcase01

    #include <assert.h>
    #include <stdlib.h>
    
    int
    main(void)
    {
            const char *list[] = { "0x", "0X", "0x?", "0X?", NULL, }, **s;
            char *t;
            long l;
            int base;
            for (s = &list[0]; *s != NULL; s++) {
                    for (base = 0; base < 36; base++) {
                            if (base == 1)
                                    continue;
                            l = strtol(*s, &t, base);
                            if (base <= 33) {
                                    assert(l == 0);
                                    assert((t - *s) == 1);
                            } else {
                                    assert(l == 33);
                                    assert((t - *s) == 2);
                            }
                    }
            }
            return (0);
    }
    
  2. Takehiko NOZAKI reporter

    testcase02

    #include <assert.h>
    #include <stdlib.h>
    
    int
    main(void)
    {
            const char *list[] = { "-0x", "-0X", "-0x?", "-0X?", NULL, }, **s;
            char *t;
            long l;
            int base;
            for (s = &list[0]; *s != NULL; s++) {
                    for (base = 0; base < 36; base++) {
                            if (base == 1)
                                    continue;
                            l = strtol(*s, &t, base);
                            if (base <= 33) {
                                    assert(l == 0);
                                    assert((t - *s) == 2);
                            } else {
                                    assert(l == -33);
                                    assert((t - *s) == 3);
                            }
                    }
            }
            return (0);
    }
    
  3. Takehiko NOZAKI reporter

    testcase03

    #include <assert.h>
    #include <stdlib.h>
    
    int
    main(void)
    {
            const char *list[] = { "+0x", "+0X", "+0x?", "+0X?", NULL, }, **s;
            char *t;
            long l;
            int base;
            for (s = &list[0]; *s != NULL; s++) {
                    for (base = 0; base < 36; base++) {
                            if (base == 1)
                                    continue;
                            l = strtol(*s, &t, base);
                            if (base <= 33) {
                                    assert(l == 0);
                                    assert((t - *s) == 2);
                            } else {
                                    assert(l == 33);
                                    assert((t - *s) == 3);
                            }
                    }
            }
            return (0);
    }
    
  4. Takehiko NOZAKI reporter

    testcase04

    #include <assert.h>
    #include <stdlib.h>
    
    int
    main(void)
    {
    #define S(s)    (" \t\n\r\f\v"/**/s)
            const char *list[] = { S("0x"), S("0X"), S("0x?"), S("0X?"), NULL, }, **s;
            char *t;
            long l;
            int base;
            for (s = &list[0]; *s != NULL; s++) {
                    for (base = 0; base < 36; base++) {
                            if (base == 1)
                                    continue;
                            l = strtol(*s, &t, base);
                            if (base <= 33) {
                                    assert(l == 0);
                                    assert((t - *s) == 7);
                            } else {
                                    assert(l == 33);
                                    assert((t - *s) == 8);
                            }
                    }
            }
            return (0);
    }
    
  5. Takehiko NOZAKI reporter

    testcase05

    #include <assert.h>
    #include <stdlib.h>
    
    int
    main(void)
    {
    #define S(s)    (" \t\n\r\f\v"/**/s)
            const char *list[] = { S("-0x"), S("-0X"), S("-0x?"), S("-0X?"), NULL, }, **s;
            char *t;
            long l;
            int base;
            for (s = &list[0]; *s != NULL; s++) {
                    for (base = 0; base < 36; base++) {
                            if (base == 1)
                                    continue;
                            l = strtol(*s, &t, base);
                            if (base <= 33) {
                                    assert(l == 0);
                                    assert((t - *s) == 8);
                            } else {
                                    assert(l == -33);
                                    assert((t - *s) == 9);
                            }
                    }
            }
            return (0);
    }
    
  6. Takehiko NOZAKI reporter

    testcase06

    #include <assert.h>
    #include <stdlib.h>
    
    int
    main(void)
    {
    #define S(s)    (" \t\n\r\f\v"/**/s)
            const char *list[] = { S("+0x"), S("+0X"), S("+0x?"), S("+0X?"), NULL, }, **s;
            char *t;
            long l;
            int base;
            for (s = &list[0]; *s != NULL; s++) {
                    for (base = 0; base < 36; base++) {
                            if (base == 1)
                                    continue;
                            l = strtol(*s, &t, base);
                            if (base <= 33) {
                                    assert(l == 0);
                                    assert((t - *s) == 8);
                            } else {
                                    assert(l == 33);
                                    assert((t - *s) == 9);
                            }
                    }
            }
            return (0);
    }
    
  7. Takehiko NOZAKI reporter

    testcase08

    #include <assert.h>
    #include <stdlib.h>
    
    int
    main(void)
    {
    #define S(s)    (" \t\n\r\f\v"/**/s)
            const char *list[] = {
                    ""    ,S("")
                    ,"?"  ,S("?")
                    ,"+"  ,S("+")
                    ,"+?" ,S("+?")
                    ,"-"  ,S("-")
                    ,"-?" ,S("-?")
                    ,NULL
            }, **s;
            char *t;
            int base;
            for (s = &list[0]; *s != NULL; s++) {
                    for (base = 0; base < 36; base++) {
                            if (base == 1)
                                    continue;
                            strtol(*s, &t, base);
                            assert(*s == t);
                    }
            }
            return (0);
    }
    
  8. Takehiko NOZAKI reporter

    testcase08

    #include <assert.h>
    #include <stdlib.h>
    
    int
    main(void)
    {
            const char *s = "FF";
            char *t;
            long l;
    
            strtol(s, &t, 0);
            assert(s == t);
    
            strtol(s, &t, 8);
            assert(s == t);
    
            strtol(s, &t, 10);
            assert(s == t);
    
            l = strtol(s, &t, 16);
            assert(l == 0xFF);
            assert((t - s) == 2 && *t == '\0');
    }
    
  9. Takehiko NOZAKI reporter

    testcase09

    #include <assert.h>
    #include <stdlib.h>
    
    int
    main(void)
    {
            const char *s = "0FF";
            char *t;
            long l;
    
            l = strtol(s, &t, 0);
            assert(l == 0);
            assert((t - s) == 1 && *t == 'F');
    
            l = strtol(s, &t, 8);
            assert(l == 0);
            assert((t - s) == 1 && *t == 'F');
    
            l = strtol(s, &t, 10);
            assert(l == 0);
            assert((t - s) == 1 && *t == 'F');
    
            l = strtol(s, &t, 16);
            assert(l == 0xFF);
            assert((t - s) == 3 && *t == '\0');
    }
    
  10. Log in to comment