Index: trunk/src/bldprogs/scm.cpp
===================================================================
--- trunk/src/bldprogs/scm.cpp	(revision 88956)
+++ trunk/src/bldprogs/scm.cpp	(revision 92185)
@@ -115,4 +115,6 @@
     SCMOPT_SKIP_SVN_SYNC_PROCESS,
     SCMOPT_DONT_SKIP_SVN_SYNC_PROCESS,
+    SCMOPT_SKIP_UNICODE_CHECKS,
+    SCMOPT_DONT_SKIP_UNICODE_CHECKS,
     SCMOPT_TAB_SIZE,
     SCMOPT_WIDTH,
@@ -203,4 +205,5 @@
     /* .fSetSvnKeywords = */                        false,
     /* .fSkipSvnSyncProcess = */                    false,
+    /* .fSkipUnicodeChecks = */                     false,
     /* .cchTab = */                                 8,
     /* .cchWidth = */                               130,
@@ -266,4 +269,6 @@
     { "--skip-svn-sync-process",            SCMOPT_SKIP_SVN_SYNC_PROCESS,           RTGETOPT_REQ_NOTHING },
     { "--dont-skip-svn-sync-process",       SCMOPT_DONT_SKIP_SVN_SYNC_PROCESS,      RTGETOPT_REQ_NOTHING },
+    { "--skip-unicode-checks",              SCMOPT_SKIP_UNICODE_CHECKS,             RTGETOPT_REQ_NOTHING },
+    { "--dont-skip-unicode-checks",         SCMOPT_DONT_SKIP_UNICODE_CHECKS,        RTGETOPT_REQ_NOTHING },
     { "--tab-size",                         SCMOPT_TAB_SIZE,                        RTGETOPT_REQ_UINT8   },
     { "--width",                            SCMOPT_WIDTH,                           RTGETOPT_REQ_UINT8   },
@@ -305,4 +310,5 @@
 SCM_REWRITER_CFG(g_SvnKeywords,                     "svn-keywords",                 rewrite_SvnKeywords);
 SCM_REWRITER_CFG(g_SvnSyncProcess,                  "svn-sync-process",             rewrite_SvnSyncProcess);
+SCM_REWRITER_CFG(g_UnicodeChecks,                   "unicode-checks",               rewrite_UnicodeChecks);
 SCM_REWRITER_CFG(g_Copyright_CstyleComment,         "copyright-c-style",            rewrite_Copyright_CstyleComment);
 SCM_REWRITER_CFG(g_Copyright_HashComment,           "copyright-hash-style",         rewrite_Copyright_HashComment);
@@ -348,4 +354,5 @@
     &g_Fix_C_and_CPP_Todos,
     &g_Fix_Err_H,
+    &g_UnicodeChecks,
     &g_C_and_CPP,
 };
@@ -356,4 +363,5 @@
     &g_SvnNoExecutable,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Makefile_kup
 };
@@ -367,4 +375,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_HashComment,
     &g_Makefile_kmk
@@ -379,4 +388,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_HashComment,
 };
@@ -391,9 +401,10 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_CstyleComment,
     &g_FixFlowerBoxMarkers,
     &g_Fix_C_and_CPP_Todos,
     &g_Fix_Err_H,
-    &g_C_and_CPP
+    &g_C_and_CPP,
 };
 
@@ -407,4 +418,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_CstyleComment,
     /// @todo &g_FixFlowerBoxMarkers,
@@ -422,4 +434,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_CstyleComment,
 };
@@ -433,4 +446,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_CstyleComment,
 };
@@ -445,4 +459,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_CstyleComment,
 };
@@ -457,4 +472,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_SemicolonComment,
 };
@@ -469,4 +485,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_SemicolonComment,
 };
@@ -478,4 +495,5 @@
     &g_StripTrailingBlanks,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_HashComment,
 };
@@ -487,4 +505,5 @@
     &g_StripTrailingBlanks,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_RemComment,
 };
@@ -496,4 +515,5 @@
     &g_StripTrailingBlanks,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_TickComment,
 };
@@ -505,4 +525,5 @@
     &g_StripTrailingBlanks,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_HashComment,
 };
@@ -516,4 +537,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_PythonComment,
 };
@@ -527,4 +549,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_HashComment,
 };
@@ -539,4 +562,5 @@
     &g_SvnNoExecutable,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_SemicolonComment,
 };
@@ -551,4 +575,5 @@
     &g_SvnNoExecutable,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_SemicolonComment,
 };
@@ -563,4 +588,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_CstyleComment,
     &g_FixFlowerBoxMarkers,
@@ -577,4 +603,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_HashComment,
 };
@@ -596,4 +623,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     /** @todo copyright is in an XML comment. */
 };
@@ -608,4 +636,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     /** @todo copyright is in an XML comment. */
 };
@@ -620,4 +649,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     /** @todo copyright is in an XML comment. */
 };
@@ -631,4 +661,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_HashComment,
 };
@@ -640,4 +671,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     /** @todo figure out copyright for Qt resource XML files. */
 };
@@ -655,4 +687,5 @@
     &g_SvnKeywords,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     /** @todo copyright is in an XML 'comment' element. */
 };
@@ -667,4 +700,5 @@
     &g_SvnNoExecutable,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_SemicolonComment,
 };
@@ -679,4 +713,5 @@
     &g_SvnNoExecutable,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_SqlComment,
 };
@@ -691,4 +726,5 @@
     &g_SvnNoExecutable,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_CstyleComment,
 };
@@ -701,4 +737,5 @@
     &g_SvnNoExecutable,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     /** @todo check for plain copyright + license in text files. */
 };
@@ -711,4 +748,5 @@
     &g_SvnNoExecutable,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
 };
 
@@ -726,4 +764,5 @@
     &g_AdjustTrailingLines,
     &g_SvnSyncProcess,
+    &g_UnicodeChecks,
     &g_Copyright_HashComment,
 };
@@ -1213,4 +1252,11 @@
         case SCMOPT_DONT_SKIP_SVN_SYNC_PROCESS:
             pSettings->fSkipSvnSyncProcess = false;
+            return VINF_SUCCESS;
+
+        case SCMOPT_SKIP_UNICODE_CHECKS:
+            pSettings->fSkipUnicodeChecks = true;
+            return VINF_SUCCESS;
+        case SCMOPT_DONT_SKIP_UNICODE_CHECKS:
+            pSettings->fSkipUnicodeChecks = false;
             return VINF_SUCCESS;
 
@@ -2829,4 +2875,5 @@
             case SCMOPT_SET_SVN_KEYWORDS:       RTPrintf("      Default: %RTbool\n", g_Defaults.fSetSvnKeywords); break;
             case SCMOPT_SKIP_SVN_SYNC_PROCESS:  RTPrintf("      Default: %RTbool\n", g_Defaults.fSkipSvnSyncProcess); break;
+            case SCMOPT_SKIP_UNICODE_CHECKS:    RTPrintf("      Default: %RTbool\n", g_Defaults.fSkipUnicodeChecks); break;
             case SCMOPT_TAB_SIZE:               RTPrintf("      Default: %u\n", g_Defaults.cchTab); break;
             case SCMOPT_WIDTH:                  RTPrintf("      Default: %u\n", g_Defaults.cchWidth); break;
Index: trunk/src/bldprogs/scm.h
===================================================================
--- trunk/src/bldprogs/scm.h	(revision 88956)
+++ trunk/src/bldprogs/scm.h	(revision 92185)
@@ -250,4 +250,5 @@
 FNSCMREWRITER rewrite_SvnKeywords;
 FNSCMREWRITER rewrite_SvnSyncProcess;
+FNSCMREWRITER rewrite_UnicodeChecks;
 FNSCMREWRITER rewrite_Copyright_CstyleComment;
 FNSCMREWRITER rewrite_Copyright_HashComment;
@@ -374,4 +375,6 @@
     /** Skip checking svn:sync-process. */
     bool            fSkipSvnSyncProcess;
+    /** Skip the unicode checks. */
+    bool            fSkipUnicodeChecks;
     /** Tab size. */
     uint8_t         cchTab;
Index: trunk/src/bldprogs/scmrw.cpp
===================================================================
--- trunk/src/bldprogs/scmrw.cpp	(revision 88956)
+++ trunk/src/bldprogs/scmrw.cpp	(revision 92185)
@@ -1059,4 +1059,74 @@
     else if (rc != VERR_NOT_FOUND)
         ScmError(pState, rc, "ScmSvnQueryProperty: %Rrc\n", rc);
+
+    return false;
+}
+
+/**
+ * Checks the that there is no bidirectional unicode fun in the file.
+ *
+ * @returns false - the state carries these kinds of changes.
+ * @param   pState              The rewriter state.
+ * @param   pIn                 The input stream.
+ * @param   pOut                The output stream.
+ * @param   pSettings           The settings.
+ */
+bool rewrite_UnicodeChecks(PSCMRWSTATE pState, PSCMSTREAM pIn, PSCMSTREAM pOut, PCSCMSETTINGSBASE pSettings)
+{
+    RT_NOREF2(pIn, pOut);
+    if (pSettings->fSkipUnicodeChecks)
+        return false;
+
+    /*
+     * Just scan the input for weird stuff and fail if we find anything we don't like.
+     */
+    uint32_t    iLine = 0;
+    SCMEOL      enmEol;
+    size_t      cchLine;
+    const char *pchLine;
+    while ((pchLine = ScmStreamGetLine(pIn, &cchLine, &enmEol)) != NULL)
+    {
+        iLine++;
+        const char *pchCur  = pchLine;
+        size_t      cchLeft = cchLine;
+        while (cchLeft > 0)
+        {
+            RTUNICP uc = 0;
+            int rc = RTStrGetCpNEx(&pchCur, &cchLeft, &uc);
+            if (RT_SUCCESS(rc))
+            {
+                const char *pszWhat;
+                switch (uc)
+                {
+                    default:
+                        continue;
+
+                    /* Potentially evil bi-directional control codes (Table I, trojan-source.pdf):  */
+                    case 0x202a: pszWhat = "LRE - left-to-right embedding"; break;
+                    case 0x202b: pszWhat = "RLE - right-to-left embedding"; break;
+                    case 0x202d: pszWhat = "LRO - left-to-right override"; break;
+                    case 0x202e: pszWhat = "RLO - right-to-left override"; break;
+                    case 0x2066: pszWhat = "LRI - left-to-right isolate"; break;
+                    case 0x2067: pszWhat = "RLI - right-to-left isolate"; break;
+                    case 0x2068: pszWhat = "FSI - first strong isolate"; break;
+                    case 0x202c: pszWhat = "PDF - pop directional formatting (LRE, RLE, LRO, RLO)"; break;
+                    case 0x2069: pszWhat = "PDI - pop directional isolate (LRI, RLI)"; break;
+
+                    /** @todo add checks for homoglyphs too. */
+                }
+#if 1
+                ScmError(pState, rc, "%u:%zu: Evil unicode codepoint: %s\n", iLine, pchCur - pchLine, pszWhat);
+#else
+                ScmVerbose(pState, 0, "%u:%zu: Evil unicode codepoint: %s\n", iLine, pchCur - pchLine, pszWhat);
+#endif
+            }
+            else
+#if 1
+                ScmError(pState, rc, "%u:%zu: Invalid UTF-8 encoding: %Rrc\n", iLine, pchCur - pchLine, rc);
+#else
+                ScmVerbose(pState, 0, "%u:%zu: Invalid UTF-8 encoding: %Rrc\n", iLine, pchCur - pchLine, rc);
+#endif
+        }
+    }
 
     return false;
