From: s_kawamoto Date: Mon, 7 Nov 2011 16:38:59 +0000 (+0900) Subject: Fix bugs of decoding INI files. X-Git-Url: http://git.osdn.net/view?p=ffftp%2Fffftp.git;a=commitdiff_plain;h=5a593299024d54015563beafb4a88d946834b276 Fix bugs of decoding INI files. Fix bugs of UTF-8 to UTF-16 API bridge. Fix bugs of arbitrary code execution. Add routines for checking UTF-8 redundant representation. Fix spelling mistakes of filenames. --- diff --git a/FFFTP.vc90.vcproj b/FFFTP.vc90.vcproj index a479903..7f15584 100644 --- a/FFFTP.vc90.vcproj +++ b/FFFTP.vc90.vcproj @@ -327,7 +327,7 @@ > > (6 * i))); + } + else if(Code & 0x03e00000) + { + i = 4; + c = (char)(0xf8 | (Code >> (6 * i))); + } + else if(Code & 0x001f0000) + { + i = 3; + c = (char)(0xf0 | (Code >> (6 * i))); + } + else if(Code & 0x0000f800) + { + i = 2; + c = (char)(0xe0 | (Code >> (6 * i))); + } + else if(Code & 0x00000780) + { + i = 1; + c = (char)(0xc0 | (Code >> (6 * i))); + } + else + { + i = 0; + c = (char)Code; + } + if(c != *p) + bResult = TRUE; + p++; + *pDst = c; + pDst++; + while(i > 0) + { + i--; + c = (char)(0x80 | ((Code >> (6 * i)) & 0x3f)); + if(c != *p) + bResult = TRUE; + p++; + *pDst = c; + pDst++; + } + } + if(*p != '\0') + bResult = TRUE; + *pDst = '\0'; + return bResult; +} + +// NULL区切りマルチバイト文字列の冗長表現を修正 +// 修正があればTRUEを返す +// 修正後の文字列の長さは元の文字列の長さ以下のためpDstとpSrcに同じ値を指定可能 +BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc) +{ + BOOL bResult; + int Length; + bResult = FALSE; + while(*pSrc != '\0') + { + Length = strlen(pSrc) + 1; + bResult = bResult | FixStringM(pDst, pSrc); + pSrc += Length; + pDst += strlen(pDst) + 1; + } + *pDst = '\0'; + return bResult; +} + +// マルチバイト文字列の冗長表現を確認 +// 冗長表現があればTRUEを返す +BOOL CheckStringM(LPCSTR lpString) +{ + BOOL bResult; + char* p; + bResult = FALSE; + p = AllocateStringM(strlen(lpString) + 1); + if(p) + { + bResult = FixStringM(p, lpString); + FreeDuplicatedString(p); + } + return bResult; +} + +// NULL区切りマルチバイト文字列の冗長表現を確認 +// 冗長表現があればTRUEを返す +BOOL CheckMultiStringM(LPCSTR lpString) +{ + BOOL bResult; + char* p; + bResult = FALSE; + p = AllocateStringM(GetMultiStringLengthM(lpString) + 1); + if(p) + { + bResult = FixMultiStringM(p, lpString); + FreeDuplicatedString(p); + } + return bResult; +} + // 文字列用に確保したメモリを開放 // リソースIDならば何もしない void FreeDuplicatedString(void* p) @@ -1857,6 +2017,7 @@ START_ROUTINE r = CopyFileW(pw0, pw1, bFailIfExists); END_ROUTINE FreeDuplicatedString(pw0); + FreeDuplicatedString(pw1); return r; } diff --git a/mbswrapper.h b/mbswrapper.h index ec153ed..6e5e6ce 100644 --- a/mbswrapper.h +++ b/mbswrapper.h @@ -238,6 +238,10 @@ wchar_t* DuplicateMtoWMultiStringBuffer(LPCSTR lpString, int size); char* DuplicateWtoM(LPCWSTR lpString, int c); wchar_t* DuplicateAtoW(LPCSTR lpString, int c); char* DuplicateWtoA(LPCWSTR lpString, int c); +BOOL FixStringM(LPSTR pDst, LPCSTR pSrc); +BOOL FixMultiStringM(LPSTR pDst, LPCSTR pSrc); +BOOL CheckStringM(LPCSTR lpString); +BOOL CheckMultiStringM(LPCSTR lpString); void FreeDuplicatedString(void* p); int WINAPI WinMainM(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); diff --git a/putty/Release/PuTTY.dll b/putty/Release/PuTTY.dll index 4ea2026..af44daf 100644 Binary files a/putty/Release/PuTTY.dll and b/putty/Release/PuTTY.dll differ diff --git a/registory.c b/registry.c similarity index 93% rename from registory.c rename to registry.c index 931c89f..1bb3b8b 100644 --- a/registory.c +++ b/registry.c @@ -1083,6 +1083,9 @@ void SaveSettingsToFile(void) { char Tmp[FMAX_PATH*2]; char Fname[FMAX_PATH+1]; + // 任意のコードが実行されるバグ修正 + char CurDir[FMAX_PATH+1]; + char SysDir[FMAX_PATH+1]; if(RegType == REGTYPE_REG) { @@ -1090,9 +1093,24 @@ void SaveSettingsToFile(void) if(SelectFile(GetMainHwnd(), Fname, MSGJPN286, MSGJPN287, "reg", OFN_EXTENSIONDIFFERENT | OFN_OVERWRITEPROMPT, 1) == TRUE) { sprintf(Tmp, "/e \x22%s\x22 HKEY_CURRENT_USER\\Software\\sota\\FFFTP", Fname); - if(ShellExecute(NULL, "open", "regedit", Tmp, ".", SW_SHOW) <= (HINSTANCE)32) + // 任意のコードが実行されるバグ修正 +// if(ShellExecute(NULL, "open", "regedit", Tmp, ".", SW_SHOW) <= (HINSTANCE)32) +// { +// MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK); +// } + if(GetCurrentDirectory(FMAX_PATH, CurDir) > 0) { - MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK); + if(GetSystemDirectory(SysDir, FMAX_PATH) > 0) + { + if(SetCurrentDirectory(SysDir)) + { + if(ShellExecute(NULL, "open", "regedit", Tmp, ".", SW_SHOW) <= (HINSTANCE)32) + { + MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK); + } + SetCurrentDirectory(CurDir); + } + } } } } @@ -1122,6 +1140,9 @@ int LoadSettingsFromFile(void) int Ret; char Tmp[FMAX_PATH*2]; char Fname[FMAX_PATH+1]; + // 任意のコードが実行されるバグ修正 + char CurDir[FMAX_PATH+1]; + char SysDir[FMAX_PATH+1]; Ret = NO; strcpy(Fname, ""); @@ -1130,15 +1151,36 @@ int LoadSettingsFromFile(void) if((strlen(Fname) >= 5) && (_stricmp(&Fname[strlen(Fname)-4], ".reg") == 0)) { sprintf(Tmp, "\x22%s\x22", Fname); - if(ShellExecute(NULL, "open", "regedit", Tmp, ".", SW_SHOW) <= (HINSTANCE)32) - { - MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK); - } - else - { - Ret = YES; - /* レジストリエディタが終了するのを待つ */ + // 任意のコードが実行されるバグ修正 +// if(ShellExecute(NULL, "open", "regedit", Tmp, ".", SW_SHOW) <= (HINSTANCE)32) +// { +// MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK); +// } +// else +// { +// Ret = YES; +// /* レジストリエディタが終了するのを待つ */ // WaitForSingleObject(Info.hProcess, INFINITE); +// } + if(GetCurrentDirectory(FMAX_PATH, CurDir) > 0) + { + if(GetSystemDirectory(SysDir, FMAX_PATH) > 0) + { + if(SetCurrentDirectory(SysDir)) + { + if(ShellExecute(NULL, "open", "regedit", Tmp, ".", SW_SHOW) <= (HINSTANCE)32) + { + MessageBox(NULL, MSGJPN285, "FFFTP", MB_OK); + } + else + { + Ret = YES; + /* レジストリエディタが終了するのを待つ */ +// WaitForSingleObject(Info.hProcess, INFINITE); + } + SetCurrentDirectory(CurDir); + } + } } } else if((strlen(Fname) >= 5) && (_stricmp(&Fname[strlen(Fname)-4], ".ini") == 0)) @@ -2273,9 +2315,9 @@ static int ReadStringFromReg(void *Handle, char *Name, char *Str, DWORD Size) int Sts; char *Pos; // UTF-8対応 + DWORD TempSize; char* pa0; wchar_t* pw0; - DWORD TempSize; Sts = FFFTP_FAIL; if(TmpRegType == REGTYPE_REG) @@ -2298,6 +2340,16 @@ static int ReadStringFromReg(void *Handle, char *Name, char *Str, DWORD Size) // Sts = FFFTP_SUCCESS; switch(IniKanjiCode) { + case KANJI_NOCNV: + TempSize = min1(Size-1, strlen(Pos)); + TempSize = StrReadIn(Pos, TempSize, Str); + *(Str + TempSize) = NUL; + Sts = FFFTP_SUCCESS; + if(!CheckStringM(Str)) + break; + Str = Str; + // UTF-8ではない可能性がある + // Shift_JISとみなす case KANJI_SJIS: if(pa0 = AllocateStringA(Size * 4)) { @@ -2315,12 +2367,6 @@ static int ReadStringFromReg(void *Handle, char *Name, char *Str, DWORD Size) FreeDuplicatedString(pa0); } break; - case KANJI_NOCNV: - Size = min1(Size-1, strlen(Pos)); - Size = StrReadIn(Pos, Size, Str); - *(Str + Size) = NUL; - Sts = FFFTP_SUCCESS; - break; } } } @@ -2378,6 +2424,10 @@ static int ReadMultiStringFromReg(void *Handle, char *Name, char *Str, DWORD Siz { int Sts; char *Pos; + // UTF-8対応 + DWORD TempSize; + char* pa0; + wchar_t* pw0; Sts = FFFTP_FAIL; if(TmpRegType == REGTYPE_REG) @@ -2393,10 +2443,42 @@ static int ReadMultiStringFromReg(void *Handle, char *Name, char *Str, DWORD Siz { if((Pos = ScanValue(Handle, Name)) != NULL) { - Size = min1(Size-1, strlen(Pos)); - Size = StrReadIn(Pos, Size, Str); - *(Str + Size) = NUL; - Sts = FFFTP_SUCCESS; + // UTF-8対応 +// Size = min1(Size-1, strlen(Pos)); +// Size = StrReadIn(Pos, Size, Str); +// *(Str + Size) = NUL; +// Sts = FFFTP_SUCCESS; + switch(IniKanjiCode) + { + case KANJI_NOCNV: + TempSize = min1(Size-1, strlen(Pos)); + TempSize = StrReadIn(Pos, TempSize, Str); + *(Str + TempSize) = NUL; + Sts = FFFTP_SUCCESS; + if(!CheckMultiStringM(Str)) + break; + // UTF-8ではない可能性がある + // Shift_JISとみなす + case KANJI_SJIS: + if(pa0 = AllocateStringA(Size * 4)) + { + if(pw0 = AllocateStringW(Size * 4 * 4)) + { + TempSize = min1((Size * 4) - 2, strlen(Pos)); + TempSize = StrReadIn(Pos, TempSize, pa0); + *(pa0 + TempSize) = NUL; + *(pa0 + TempSize + 1) = NUL; + AtoWMultiString(pw0, Size * 4 * 4, pa0); + WtoMMultiString(Str, Size, pw0); + TerminateStringM(Str, Size); + TerminateStringM(Str, Size - 1); + Sts = FFFTP_SUCCESS; + FreeDuplicatedString(pw0); + } + FreeDuplicatedString(pa0); + } + break; + } } } return(Sts);