Don't use StringBuilderCache for casing
During code review, Steve proposed we moved to using StringBuilderCache
to the allocation of the temporary char[] array during casing
operations. I made the change but later realized that this caused a few
issues.
- The native layer operates on UChar/length pairs, not null terminated
strings. Because of this, we don't actually write a terminating null
into the destination buffer (since we just do a 1:1 casing operation
on the input and never see the null terminator). However, the
marshalling code for StringBuilder assumes the buffer will be null
terminated and uses that to compute the new length value after a
marshalling call. Because there can be left over data from previous
calls in the buffer the string length calculation will be incorrect
and we will end up leaking in extra data into the cased string.
- The StringBuilder marshalling as a whole won't work if we have
embdedded nulls in a string (we'll end up dropping characters on the
transition from native back to managed) but that's something that we
need to be able to handle.
Ideally there would be a way to construct a mutable string, case into
its buffer and the freeze the string, but we don't have a way to do that
today, so we need to stick with this allocation.