int char_len; /* bytes in current character */
int w;
wchar_t wide_char;
+ char *altstr = NULL;
#endif
char *sp; /* current position in source string */
char *cp = *dest; /* current position in destination string */
#ifdef MULTIBYTE_SUPPORT
char_len = mbtowc(&wide_char, sp, end);
+ /*
+ * See the relevant comments in cpstripped() to explain what's
+ * going on here; we want to handle the case where we get
+ * characters that mbtowc() cannot handle
+ */
+
+ if (char_len < 0) {
+ altstr = "?";
+ char_len = mbtowc(&wide_char, altstr, 1);
+ }
+
if (char_len <= 0)
break;
#ifdef MULTIBYTE_SUPPORT
if (w >= 0 && remaining >= w) {
- strncpy(cp, sp, char_len);
+ strncpy(cp, altstr ? altstr : sp, char_len);
cp += char_len;
remaining -= w;
+ altstr = NULL;
}
sp += char_len;
#else
#ifdef MULTIBYTE_SUPPORT
int char_len, w;
wchar_t wide_char;
+ char *altstr = NULL;
#endif /* MULTIBYTE_SUPPORT */
if (!str)
*end += char_len - w;
}
+ /*
+ * If mbrtowc() failed, then we have a character that isn't valid
+ * in the current encoding. Replace it with a '?'. We do that by
+ * setting the alstr variable to the value of the replacement string;
+ * altstr is used below when the bytes are copied into the output
+ * buffer.
+ */
+
+ if (char_len < 0) {
+ altstr = "?";
+ char_len = mbtowc(&wide_char, altstr, 1);
+ }
+
if (char_len <= 0 || *dest + char_len > *end)
break;
prevCtrl = 0;
#ifdef MULTIBYTE_SUPPORT
- memcpy(*dest, str, char_len);
+ memcpy(*dest, altstr ? altstr : str, char_len);
str += char_len;
*dest += char_len;
+ altstr = NULL;
#else /* MULTIBYE_SUPPORT */
*(*dest)++ = *str++
#endif /* MULTIBYTE_SUPPORT */