strtol(3) and wcstol(3) family wrongly update endptr when parsing "0x".
Issue #64
closed
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)
-
reporter -
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); }
-
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); }
-
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); }
-
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); }
-
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); }
-
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); }
-
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'); }
-
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'); }
-
reporter -
reporter - changed status to resolved
BUGFIX: Issue
#64-- strtol(3) and wcstol(3) family wrongly update endptr when parsing "0x".→ <<cset 017135430514>>
-
reporter BUGFIX: Issue
#65-- wcstol(3) family get 400% slower than before Issue#64fixes.→ <<cset 92477ea20847>>
-
reporter - changed status to closed
- Log in to comment
testcase01