Lately my team got a work item for removing all the usage of lstrlen. lstrlen, as we found out during investigation, contains a SEH try block that swallows exception. So what’s the big deal? Think about this scenario: Usually, dereferencing a non-null invalid pointer cause the thread AV like this:
PWSTR sz = 0x05; // 0x00000005 is invalid, but not NULL
wcslen(sz); // Die die die. thanks for the invalid pointer
However, if you replace wcslen with lstrlen, your app won’t crash. It won’t crash because lstrlen handles the EXCEPTION_ACCESS_VIOLATION exceptions and “gracefully” returns 0. This is awful, thank you very much.
So why it is awful?
It is awful because it hides an error that shouldn’t happen at the first place. In the case above, the pointer ‘sz’ should never be pointing to 0x0005. If it ever happens, it means the process is already in a unexpected bad state. Bad states has high likelihood to corrupt user data, which is really the last thing an user wants. So when the process is in bad state, the only responsible thing to do is to terminate it ASAP. The longer the process survived, the more trouble it will make, period.
So why not to get the lazy Microsoft guys fix their broken code?
Isn’t its Microsoft’s responsibility to fix this behavior? After all, they own the code. Well, to be fair, they can’t. They can’t not because they’re too lazy. They can’t because there are existing application running in millions of computers that actually rely on this behavior to survive. Fixing this problem, although this is arguably the right thing to do, will make previously running apps crash. When you have an OS that cause a million app crash everyday, regardless who is ultimately responsible for the error, you call it Windows Vista. Not only making MS look ass sucking, but also cause real damage to their customer. So what can they do? Well, nothing, absolutely, sadly, nothing. They would have to spend the rest of their life, looking at mirror, and feel bad about designing such a bad API. I hope the very developer who designed this API can sleep at night.
The moral of this story is, when you design your function, especially library functions, be as straightforward as possible. When in error, fail the operation and report it. When it should crash, crash bravely and responsibly. Trust me, people blame Microsoft anyways.