By my understanding, strcmp()
(no 'n'), upon seeing a null character in either argument, immediately stops processing and returns a result.
Therefore, if one of the arguments is known with 100% certainty to be null-terminated (e.g. it is a string literal), there is no security benefit whatsoever in using strncmp()
(with 'n') with a call to strlen()
as part of the third argument to limit the comparison to the known string length, because strcmp()
will already never read more characters than are in that known-terminating string.
In fact, it seems to me that a call to strncmp()
whose length argument is a strlen()
on one of the first two arguments is only different from the strcmp()
case in that it wastes time linear in the size of the known-terminating string by evaluating the strlen()
expression.
Consider:
Sample code A:
if (strcmp(user_input, "status") == 0)
reply_with_status();
Sample code B:
if (strncmp(user_input, "status", strlen("status")+1) == 0)
reply_with_status();
Is there any benefit to the former over the latter? Because I see it in other people's code a lot.
Do I have a flawed understanding of how these functions work?
In your particular example, I would say it's detrimental to use strncmp
because of:
strlen
does the scan anyway"status"
All these add to clutter, and in neither case would you be protected from overflowing user_input
if it indeed was shorter than 6 characters and contained the same characters as the test string.
That would be exceptional. If you know that your input string always has more memory than the number of characters in your test strings, then don't worry. Otherwise, you might need to worry, or at least consider it. strncmp
is useful for testing stuff inside large buffers.
My preference is for code readability.
Yes it does. If you use strlen in a strncmp, it will traverse the pointer until it sees a null in the string. That makes it functionally equivalent to strcmp.
In the particular case you've given, it's indeed useless. However, a slight alteration is more common:
if (strncmp(user_input, "status", strlen("status")) == 0)
reply_with_status();
This version just checks if user_input
starts with "status"
, so it has different semantics.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With