Errors in strtoul() implementation
Closed this issue · 3 comments
tomlogic commented
Compare output of this test program in gcc to Dynamic C. Pay particular attention to the value of *tailptr, and how it relates to sptr.
#include <stdlib.h>
#include <stdio.h>
void test( char *str, int base)
{
char *tail;
unsigned long result;
result = strtoul( str, &tail, base);
printf( "strtoul( \"%s\", &tail, %u) = %lu (tail = \"%s\")\n",
str, base, result, tail);
}
int main (int argc, char *argv[])
{
test( " 123", 0);
test( " 123", 1);
test( " 999", 8);
return 0;
}
results with gcc:
strtoul( " 123", &tail, 0) = 123 (tail = "")
strtoul( " 123", &tail, 1) = 0 (tail = " 123")
strtoul( " 999", &tail, 8) = 0 (tail = " 999")
DrASK commented
What is the output from Dynamic C? Also, it would be helpful to see the value of errno
as the value of tail
is unspecified when base is invalid (the second call).
tomlogic commented
Updated test program:
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
void test_unsigned(char *str, int base)
{
char *tail;
unsigned long result;
errno = 0;
result = strtoul( str, &tail, base);
printf("strtoul(\"%s\", &tail, %u) = %lu (tail=\"%s\", errno=%d)\n",
str, base, result, tail, errno);
}
void test_signed(char *str, int base)
{
char *tail;
long result;
errno = 0;
result = strtol( str, &tail, base);
printf("strtol(\"%s\", &tail, %u) = %ld (tail=\"%s\", errno=%d)\n",
str, base, result, tail, errno);
}
void test(char *str, int base)
{
test_unsigned(str, base);
test_signed(str, base);
}
int main()
{
printf("EINVAL=%d, ERANGE=%d, LONG_MAX=%ld ULONG_MAX=%lu\n",
EINVAL, ERANGE, LONG_MAX, ULONG_MAX);
test(" 123", 0);
test(" 123", 1);
test(" 999", 8);
test("9999999999999999999", 0);
return 0;
}
gcc results:
EINVAL=22, ERANGE=34, LONG_MAX=2147483647 ULONG_MAX=4294967295
strtoul(" 123", &tail, 0) = 123 (tail="", errno=0)
strtol(" 123", &tail, 0) = 123 (tail="", errno=0)
strtoul(" 123", &tail, 1) = 0 (tail=" 123", errno=22)
strtol(" 123", &tail, 1) = 0 (tail=" 123", errno=22)
strtoul(" 999", &tail, 8) = 0 (tail=" 999", errno=0)
strtol(" 999", &tail, 8) = 0 (tail=" 999", errno=0)
strtoul("9999999999999999999", &tail, 0) = 4294967295 (tail="", errno=34)
strtol("9999999999999999999", &tail, 0) = 2147483647 (tail="", errno=34)
Original Dynamic C results:
EINVAL=22, ERANGE=711, LONG_MAX=2147483647 ULONG_MAX=4294967295
strtoul(" 123", &tail, 0) = 123 (tail="", errno=0)
strtol(" 123", &tail, 0) = 123 (tail="", errno=0)
strtoul(" 123", &tail, 1) = 0 (tail="123", errno=0)
strtol(" 123", &tail, 1) = 0 (tail=" 123", errno=0)
strtoul(" 999", &tail, 8) = 0 (tail="999", errno=0)
strtol(" 999", &tail, 8) = 0 (tail="999", errno=0)
strtoul("9999999999999999999", &tail, 0) = 4294967295 (tail="", errno=711)
strtol("9999999999999999999", &tail, 0) = 2147483647 (tail="", errno=711)
With Dynamic C changes (not yet committed):
EINVAL=22, ERANGE=711, LONG_MAX=2147483647 ULONG_MAX=4294967295
strtoul(" 123", &tail, 0) = 123 (tail="", errno=0)
strtol(" 123", &tail, 0) = 123 (tail="", errno=0)
strtoul(" 123", &tail, 1) = 0 (tail=" 123", errno=22)
strtol(" 123", &tail, 1) = 0 (tail=" 123", errno=22)
strtoul(" 999", &tail, 8) = 0 (tail=" 999", errno=0)
strtol(" 999", &tail, 8) = 0 (tail=" 999", errno=0)
strtoul("9999999999999999999", &tail, 0) = 4294967295 (tail="", errno=711)
strtol("9999999999999999999", &tail, 0) = 2147483647 (tail="", errno=711)
DrASK commented
Looks like a good fix.