Suppose I have this function. It takes a Data object, makes a mutable copy, appends a byte to the beginning of the copy, and logs the result.
Seems reasonable enough, right? (Well, other than the expense of memmove'ing the whole data, but set that aside for a moment.) But. But! Every Data object can potentially be a slice. And if this Data happens to be a slice... well...
For some reason, the slice's startIndex seems to have migrated four bytes to the right, and the endIndex seems to go beyond the end of the buffer into random memory. And, that byte we tried to insert at the beginning got inserted somewhere in the middle instead. Huh.
What happens if we delete something from the beginning of our Data, instead of add to it? Well:
Once again, the startIndex seems to have migrated four bytes to the right, we've got some random memory at the end, and instead of the first byte, we deleted something right in the middle. Okay.
What happens if we add something to the end, you're wondering? Well, clearly the correct behavior for that case is to segfault.
Clearly, something is afoot with Data slices. You're shocked, I know. This should probably be fixed.
Just declare the result of using a data slice for any purpose as "undefined behavior."
In all seriousness, it appears that the blame lies in the Copy-On-Write behavior for Data slices. If the startIndex is shifted from the beginning of the original Data (in this case, by four bytes), that shift gets re-applied to the slice, causing the shift to be twice as large as it should be. You could say... the COW gets tipped. I'll see myself out.