On 1 January 2016 at 16:11, Eli Zaretskii <[email protected]> wrote: >> BTW this strikes me as strange: >> >> Reading from location 01a4ffff >> >> The ffff would make sense if memory protection was done in blocks of >> 10000 (hex), and here we've strayed into a protected part of memory. >> But I expect it would be more likely to read bytes in increasing >> order, meaning we'd stray into xxx0000. If changing the argument to >> mbrtowc fixes the problem, we needn't worry about it. > > Strange indeed. > > Btw, in case it wasn't clear: the mbrtowc that's used here is the one > from Gnulib, not from the MS-Windows runtime. According to > disassembly of gnulib/lib/mbrtowc.o, it's the rpl_mbrtowc variant > (near the end of the file) that's used in my case.
I had an idea for how that value could be obtained. The pointer is advanced according to the return value of mbrtowc, and mbrtowc returns -1 for an error. But the return type of mbrtowc is unsigned, so I did: if ((long) mbrlen(p, len, NULL) > 0) and similar. However, if size_t is a narrower type than long (e.g. size_t 32 bits, long 64 bits) then a negative value might still end up as positive, I think. The error isn't caught and we go back one byte. I wonder if it should be if ((ptrdiff_t) mbrlen(p, len, NULL) > 0) or more verbosely, but more likely size_t status = mbrlen(p, len, NULL); if (status == (size_t) -1 || status == (size_t) -2)
