Browse Source

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.
rdb 5 years ago
parent
commit
ab6bf5f4f7

+ 1 - 1
direct/src/dcparser/dcPacker.cxx

@@ -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;

+ 5 - 0
direct/src/plugin/p3dStringObject.cxx

@@ -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;
       }

+ 4 - 0
dtool/src/interrogate/interfaceMakerPythonNative.cxx

@@ -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)

+ 6 - 3
dtool/src/prckeys/makePrcKey.cxx

@@ -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;
       }