general: Add workaround for Windows bug in various uses of isprint()

See #994; there is a regression in certain versions of the Windows CRT that gives the wrong result for isprint().  This adds workarounds to various potentially affected locations where isprint() is being used.
This commit is contained in:
rdb 2020-08-21 14:51:42 +02:00
parent 9deb569441
commit ab6bf5f4f7
4 changed files with 16 additions and 4 deletions

View File

@ -1102,7 +1102,7 @@ enquote_string(ostream &out, char quote_mark, const string &str) {
if ((*pi) == quote_mark || (*pi) == '\\') {
out << '\\' << (*pi);
} else if (!isprint(*pi)) {
} else if (!isprint(*pi) || (*pi) == '\t') {
char buffer[10];
sprintf(buffer, "%02x", (unsigned char)(*pi));
out << "\\x" << buffer;

View File

@ -83,6 +83,11 @@ output(std::ostream &out) {
out << "\\\x22";
break;
case '\t':
// Certain versions of the Windows CRT classify tab as printable.
out << "\\t";
break;
default:
out << *si;
}

View File

@ -8019,6 +8019,10 @@ output_quoted(ostream &out, int indent_level, const std::string &str,
<< '"';
continue;
case '\t':
out << "\\t";
break;
default:
if (!isprint(*si)) {
out << "\\" << oct << std::setw(3) << std::setfill('0') << (unsigned int)(*si)

View File

@ -93,10 +93,13 @@ output_c_string(std::ostream &out, const string &string_name,
last_nl = false;
}
if (isprint(data_ptr[i])) {
if (data_ptr[i] == '\t') {
out << "\\t";
}
else if (isprint(data_ptr[i])) {
out << data_ptr[i];
} else {
}
else {
out << "\\x" << std::hex << std::setw(2) << std::setfill('0')
<< (unsigned int)(unsigned char)data_ptr[i] << std::dec;
}