Any buffer over runs in this char 'toHexStr' code?

Started by
19 comments, last by SiCrane 12 years, 4 months ago
Hi guys, does this code have any safety issues?



const char *tohexstr1(const char *src, size_t srclen, char* dst, int dstlen)
{
assert(dstlen > 1);
char temp[3];
int len = 0;
*dst = 0;
for (size_t i = 0; i < srclen; ++i) {
sprintf(temp, "%02X", src);
temp[2] = 0;
len += 2;

if (len < dstlen)
strcat(dst, temp);
}
return dst;
}


Thanks in advance!
[size=2]aliak.net
Advertisement
looks ok if srclen doesn't include '\0' (but it looks like its raw data anyhow).

this won't build the entire string if dstlen is too small.. (if this isn't intentional, you could just 'if (srclen * 2 <= dstlen) doesnt_fit;' at the start.

you could avoid the temp, and just use a 'sprintf(dst + len, "%02x", src)' (sprintf will append a '\0').

maybe you meant 'assert(dstlen >= 1)', since srclen may be 0.
Thanks! Yeah the temp can be avoided indeed.
Entire string doesn't have to be built so that's ok.
Assert(dstlen >= 1) it should be.

Also, when srclen does include the \0 then that's considered a safer case then when it does not right?
[size=2]aliak.net
If srclen does include the '\0', you will have a "00" appended to dst.
You aren't checking if src or dst are null. You aren't checking the return value of sprintf() (though it would be very surprising for it to fail). The function doesn't indicate if it fails to convert the buffer to hex (e.g. src or dst null, not enough room in dst).

Using assert() rather than an unconditional test allows that test to be skipped in production code. If you're serious about buffer overruns and security, you're serious enough to always do the check.

I can't see anything else, but its been a while since I've been immersed in low level C. It does without saying that the function puts pressure on the callers to ensure that the sizes match the actual sizes of the buffers.


If srclen does include the '\0', you will have a "00" appended to dst.
[/quote]
Is that not what is desired? I'm not sure what your objection to the case there src includes a NUL character is?
[s]I think it can overflow dest by two entries. For example try this:


char test[5];
test[3] = 0;
test[4] = 'z';
tohexstr1("aa", 2, test, 3);
assert(test[3] == 0);
assert(test[4] == 'z');
[/s]

Edit: This won't make it overflow.
Your test seems to pass Adam_42?
Ahh yeah, oops. I didn't check it with a compiler and didn't quite work the logic through in my head correctly. Somehow I thought the +=2 was in the wrong place compared to the test.
Fun fact: integral types like char, undergo integer promotion when passed to ellipses functions like sprintf(). That means that if char is signed on your platform (which is a popular choice), int is 32-bits, and if src is 0xFF, sprintf("%02X", src) won't try to write "FF" to the buffer, it'll try to write "FFFFFFFF" to the buffer. Your buffer has a length of 3.

Less of a concern is that if char isn't 8 bits on your platform, you may also get a buffer overflow. I'd still stick in a static assertion of some sort.
Yes, there is a possible buffer overflow. If the input contains negative chars (it is up to the compiler whether char is a signed or unsigned type), sprintf will write past the end of temp.

This topic is closed to new replies.

Advertisement