Skip to content

Commit

Permalink
Removing BOM from INI files if encoded as UTF8-BOM
Browse files Browse the repository at this point in the history
  • Loading branch information
shriprem committed Jul 7, 2022
1 parent 9bdcfbd commit d7d7abb
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 44 deletions.
86 changes: 56 additions & 30 deletions src/ConfigIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -507,69 +507,95 @@ void ConfigIO::viewBackupFolder() {
ShellExecute(NULL, L"open", pluginConfigBackupDir, NULL, NULL, SW_SHOWNORMAL);
}

bool ConfigIO::checkConfigFilesforUCS16() {
bool ConfigIO::checkConfigFilesforUTF8() {
bool status{ true };

if (!fixIfUTF16File(WCONFIG_FILE_PATHS[CONFIG_VIZ]))
if (!fixIfNotUTF8File(WCONFIG_FILE_PATHS[CONFIG_VIZ]))
status = false;

if (!fixIfUTF16File(WCONFIG_FILE_PATHS[CONFIG_THEMES]))
if (!fixIfNotUTF8File(WCONFIG_FILE_PATHS[CONFIG_THEMES]))
status = false;

if (!fixIfUTF16File(WCONFIG_FILE_PATHS[CONFIG_FOLDSTRUCTS]))
if (!fixIfNotUTF8File(WCONFIG_FILE_PATHS[CONFIG_FOLDSTRUCTS]))
status = false;

return status;
}

bool ConfigIO::fixIfUTF16File(CF_TYPES cfType) {
bool ConfigIO::fixIfNotUTF8File(CF_TYPES cfType) {
if (cfType < 0 || cfType >= CONFIG_FILE_COUNT) return false;

return fixIfUTF16File(WCONFIG_FILE_PATHS[cfType]);
return fixIfNotUTF8File(WCONFIG_FILE_PATHS[cfType]);
}

bool ConfigIO::fixIfUTF16File(wstring file) {
if (!hasBOM(file)) return true;

convertFromUTF16ToUTF8(file);

return hasBOM(file);
}

bool ConfigIO::hasBOM(wstring file) {
ConfigIO::ENC_TYPE ConfigIO::getBOM(wstring file) {
using std::ios;

if (std::wifstream fs{ file, ios::binary }) {
unsigned short bom[2]{};
unsigned short bom[3]{};
bom[0] = fs.get();
bom[1] = fs.get();

return (bom[0] == 0xFF && bom[1] == 0xFE) || (bom[0] == 0xFE && bom[1] == 0xFF);
bom[2] = fs.get();
fs.close();

if (bom[0] == 0xFF && bom[1] == 0xFE)
return UCS16_LE;
else if (bom[0] == 0xFE && bom[1] == 0xFF)
return UCS16_BE;
else if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF)
return UTF8_BOM;
}

return true;
return UTF8;
}

void ConfigIO::convertFromUTF16ToUTF8(wstring file) {
bool ConfigIO::fixIfNotUTF8File(wstring file) {
using std::ios;

ENC_TYPE encoding{ getBOM(file) };
if (encoding == UTF8) return true;

backupConfigFile(file);

if (std::wifstream wifs{ file, ios::binary | ios::ate }) {
wifs.imbue(std::locale(wifs.getloc(),
new std::codecvt_utf16<wchar_t, 0x10FFFF, std::consume_header>));
switch (encoding)
{
case UTF8_BOM:
if (std::ifstream ifs{ file, ios::binary | ios::ate }) {
int size = static_cast<int>(ifs.tellg()) - 3;
string str(size, '\0');
ifs.seekg(3);
ifs.read(str.data(), size);
ifs.close();

string mbData{ str.c_str() };

if (std::ofstream ofs{ file, ios::out | ios::binary | ios::trunc}) {
ofs.write(mbData.c_str(), mbData.length());
}
}
break;

case UCS16_BE:
case UCS16_LE:
if (std::wifstream wifs{ file, ios::binary | ios::ate }) {
wifs.imbue(std::locale(wifs.getloc(), new std::codecvt_utf16<wchar_t, 0x10FFFF, std::consume_header>));

int size = static_cast<int>(wifs.tellg());
wstring wstr(size, '\0');
wifs.seekg(0);
wifs.read(wstr.data(), size);
int size = static_cast<int>(wifs.tellg());
wstring wstr(size, '\0');
wifs.seekg(0);
wifs.read(wstr.data(), size);
wifs.close();

string mbData{ Utils::WideToNarrow(wstr).c_str() };
string mbData{ Utils::WideToNarrow(wstr).c_str() };

if (std::ofstream ofs{ file, ios::out | ios::binary | ios::trunc }) {
ofs.write(mbData.c_str(), mbData.length());
if (std::ofstream ofs{ file, ios::out | ios::binary | ios::trunc }) {
ofs.write(mbData.c_str(), mbData.length());
}
}
break;
}

return (getBOM(file) == UTF8);
}

void ConfigIO::flushConfigFile() {
Expand Down
17 changes: 12 additions & 5 deletions src/ConfigIO.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,9 @@ class ConfigIO {
void viewBackupFolder();
void flushConfigFile();

bool checkConfigFilesforUCS16();
bool fixIfUTF16File(CF_TYPES cfType);
bool fixIfUTF16File(wstring file);
bool hasBOM(wstring file);
void convertFromUTF16ToUTF8(wstring file);
bool checkConfigFilesforUTF8();
bool fixIfNotUTF8File(CF_TYPES cfType);
bool fixIfNotUTF8File(wstring file);

protected:
TCHAR pluginConfigDir[MAX_PATH]{};
Expand All @@ -145,5 +143,14 @@ class ConfigIO {

wstring wCurrentConfigFile{}, wCurrentThemeFile{}, wCurrentFoldStructFile{};
string currentConfigFile{}, currentThemeFile{}, currentFoldStructFile{};

enum ENC_TYPE {
UTF8,
UTF8_BOM,
UCS16_LE,
UCS16_BE
};

ENC_TYPE getBOM(wstring file);
};

2 changes: 1 addition & 1 deletion src/Dialogs/ConfigureDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ INT_PTR CALLBACK ConfigureDialog::run_dlgProc(UINT message, WPARAM wParam, LPARA
wstring backupConfigFile;

if (_configIO.queryConfigFileName(_hSelf, TRUE, TRUE, backupConfigFile)) {
if (_configIO.fixIfUTF16File(backupConfigFile)) {
if (_configIO.fixIfNotUTF8File(backupConfigFile)) {
configFile = backupConfigFile;
loadConfigInfo();
fillFileTypes();
Expand Down
2 changes: 1 addition & 1 deletion src/Dialogs/EximFileTypeDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ void EximFileTypeDialog::loadExtractFile() {
wstring sExtractFile{};

if (_configIO.queryConfigFileName(_hSelf, TRUE, FALSE, sExtractFile)) {
if (_configIO.fixIfUTF16File(sExtractFile)) {
if (_configIO.fixIfNotUTF8File(sExtractFile)) {
string sExtractData{ _configIO.readConfigFile(sExtractFile) };
SetDlgItemText(_hSelf, IDC_FTEXIM_EDIT_CNTRL, Utils::NarrowToWide(sExtractData).c_str());
}
Expand Down
2 changes: 1 addition & 1 deletion src/Dialogs/ThemeDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ INT_PTR CALLBACK ThemeDialog::run_dlgProc(UINT message, WPARAM wParam, LPARAM lP
wstring backupThemeFile;

if (_configIO.queryConfigFileName(_hSelf, TRUE, TRUE, backupThemeFile)) {
if (_configIO.fixIfUTF16File(backupThemeFile)) {
if (_configIO.fixIfNotUTF8File(backupThemeFile)) {
themeFile = backupThemeFile;
loadConfigInfo();
fillThemes();
Expand Down
12 changes: 6 additions & 6 deletions src/Dialogs/VisualizerPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ INT_PTR CALLBACK VisualizerPanel::run_dlgProc(UINT message, WPARAM wParam, LPARA
break;

case IDC_VIZPANEL_FILETYPE_CONFIG:
if (_configIO.fixIfUTF16File(_configIO.CONFIG_VIZ))
if (_configIO.fixIfNotUTF8File(_configIO.CONFIG_VIZ))
ShowConfigDialog();
break;

Expand All @@ -63,7 +63,7 @@ INT_PTR CALLBACK VisualizerPanel::run_dlgProc(UINT message, WPARAM wParam, LPARA
break;

case IDC_VIZPANEL_THEME_CONFIG:
if (_configIO.fixIfUTF16File(_configIO.CONFIG_THEMES))
if (_configIO.fixIfNotUTF8File(_configIO.CONFIG_THEMES))
ShowThemeDialog();
break;

Expand Down Expand Up @@ -161,12 +161,12 @@ INT_PTR CALLBACK VisualizerPanel::run_dlgProc(UINT message, WPARAM wParam, LPARA
}

case IDC_VIZPANEL_EXTRACT_DATA_BTN:
if (_configIO.fixIfUTF16File(_configIO.CONFIG_EXTRACTS))
if (_configIO.fixIfNotUTF8File(_configIO.CONFIG_EXTRACTS))
showExtractDialog();
break;

case IDC_VIZPANEL_FOLDING_APPLY_BTN:
if (_configIO.fixIfUTF16File(_configIO.CONFIG_FOLDSTRUCTS))
if (_configIO.fixIfNotUTF8File(_configIO.CONFIG_FOLDSTRUCTS))
applyFolding("");
setFocusOnEditor();
break;
Expand Down Expand Up @@ -286,7 +286,7 @@ void VisualizerPanel::initPanel() {
using Utils::loadBitmap;
using Utils::setFont;

utf8Config = _configIO.checkConfigFilesforUCS16();
utf8Config = _configIO.checkConfigFilesforUTF8();
if (!utf8Config) return;

PreferencesDialog::applyFoldLineColorAlpha();
Expand Down Expand Up @@ -1576,7 +1576,7 @@ void VisualizerPanel::showExtractDialog() {

bool VisualizerPanel::detectFileType(HWND hScintilla, string& fileType) {
if (!isVisible()) return FALSE;
if (!_configIO.checkConfigFilesforUCS16()) return FALSE;
if (!_configIO.checkConfigFilesforUTF8()) return FALSE;

string lineTextCStr(FW_LINE_MAX_LENGTH, '\0');
size_t startPos, endPos;
Expand Down

0 comments on commit d7d7abb

Please sign in to comment.