diff options
author | p0358 <p0358@users.noreply.github.com> | 2023-01-06 19:00:42 +0100 |
---|---|---|
committer | GeckoEidechse <gecko.eidechse+git@pm.me> | 2023-01-06 19:03:07 +0100 |
commit | a9db977bf04973c22f99c4866b0fc43d57cc7ccd (patch) | |
tree | ee46ff15309a79e20a5ba5ef2b0d02a9636f3fcb /NorthstarDLL/util/utils.cpp | |
parent | 7133fe80c6615297dfef3653981e766ff5d56038 (diff) | |
download | NorthstarLauncher-a9db977bf04973c22f99c4866b0fc43d57cc7ccd.tar.gz NorthstarLauncher-a9db977bf04973c22f99c4866b0fc43d57cc7ccd.zip |
Fix issues of restriction of chat message charset (#391)v1.11.4-rc1v1.11.41.11.X
Diffstat (limited to 'NorthstarDLL/util/utils.cpp')
-rw-r--r-- | NorthstarDLL/util/utils.cpp | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/NorthstarDLL/util/utils.cpp b/NorthstarDLL/util/utils.cpp new file mode 100644 index 00000000..10c5b26d --- /dev/null +++ b/NorthstarDLL/util/utils.cpp @@ -0,0 +1,83 @@ +#include "pch.h" +#include <ctype.h> +#include "utils.h" + +bool skip_valid_ansi_csi_sgr(char*& str) +{ + if (*str++ != '\x1B') + return false; + if (*str++ != '[') // CSI + return false; + for (char* c = str; *c; c++) + { + if (*c >= '0' && *c <= '9') + continue; + if (*c == ';' || *c == ':') + continue; + if (*c == 'm') // SGR + break; + return false; + } + return true; +} + +void NS::Utils::RemoveAsciiControlSequences(char* str, bool allow_color_codes) +{ + for (char *pc = str, c = *pc; c = *pc; pc++) + { + // skip UTF-8 characters + int bytesToSkip = 0; + if ((c & 0xE0) == 0xC0) + bytesToSkip = 1; // skip 2-byte UTF-8 sequence + if ((c & 0xF0) == 0xE0) + bytesToSkip = 2; // skip 3-byte UTF-8 sequence + if ((c & 0xF8) == 0xF0) + bytesToSkip = 3; // skip 4-byte UTF-8 sequence + if ((c & 0xFC) == 0xF8) + bytesToSkip = 4; // skip 5-byte UTF-8 sequence + if ((c & 0xFE) == 0xFC) + bytesToSkip = 5; // skip 6-byte UTF-8 sequence + + bool invalid = false; + char* orgpc = pc; + for (int i = 0; i < bytesToSkip; i++) + { + char next = pc[1]; + + // valid UTF-8 part + if ((next & 0xC0) == 0x80) + { + pc++; + continue; + } + + // invalid UTF-8 part or encountered \0 + invalid = true; + break; + } + if (invalid) + { + // erase the whole "UTF-8" sequence + for (char* x = orgpc; x <= pc; x++) + if (*x != '\0') + *x = ' '; + else + break; + } + if (bytesToSkip > 0) + continue; // this byte was already handled as UTF-8 + + // an invalid control character or an UTF-8 part outside of UTF-8 sequence + if ((iscntrl(c) && c != '\n' && c != '\r' && c != '\x1B') || (c & 0x80) != 0) + { + *pc = ' '; + continue; + } + + if (c == '\x1B') // separate handling for this escape sequence... + if (allow_color_codes && skip_valid_ansi_csi_sgr(pc)) // ...which we allow for color codes... + pc--; + else // ...but remove it otherwise + *pc = ' '; + } +} |