Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my (re)implementation of strlen wrong?

I came up with this little code but all the professionals said its dangerous and I should not write code like this. Can anyone highlight its vulnerabilities in 'more' details?

int strlen(char *s){ 
    return (*s) ? 1 + strlen(s + 1) : 0; 
}
like image 535
Bálint Juhász Avatar asked Nov 30 '22 20:11

Bálint Juhász


2 Answers

It has no vulnerabilities per se, this is perfectly correct code. It is prematurely pessimized, of course. It will run out of stack space for anything but the shortest strings, and its performance will suck due to recursive calls, but otherwise it's OK.

The tail call optimization most likely won't cope with such code. If you want to live dangerously and depend on tail-call optimizations, you should rephrase it to use the tail-call:

// note: size_t is an unsigned integertype

int strlen_impl(const char *s, size_t len) {
    if (*s == 0) return len;
    if (len + 1 < len) return len; // protect from overflows
    return strlen_impl(s+1, len+1);
}        

int strlen(const char *s) {
   return strlen_impl(s, 0);
}
like image 96
Kuba hasn't forgotten Monica Avatar answered Dec 03 '22 08:12

Kuba hasn't forgotten Monica


Dangerous it a bit of a stretch, but it is needlessly recursive and likely to be less efficient than the iterative alternative.

I suppose also that given a very long string there is a danger of a stack overflow.

like image 39
john Avatar answered Dec 03 '22 09:12

john