OSDN Git Service

Fix bugs of uninitialized variables.
authors_kawamoto <s_kawamoto@users.sourceforge.jp>
Fri, 9 Mar 2012 04:29:14 +0000 (13:29 +0900)
committers_kawamoto <s_kawamoto@users.sourceforge.jp>
Fri, 9 Mar 2012 04:29:14 +0000 (13:29 +0900)
Fix bugs of conversion of character encoding.

FFFTP_Eng_Release/FFFTP.exe
Release/FFFTP.exe
codecnv.c
common.h
filelist.c

index 245590b..c97d7a3 100644 (file)
Binary files a/FFFTP_Eng_Release/FFFTP.exe and b/FFFTP_Eng_Release/FFFTP.exe differ
index aace87a..8ef225b 100644 (file)
Binary files a/Release/FFFTP.exe and b/Release/FFFTP.exe differ
index 19c4d6b..a313d1a 100644 (file)
--- a/codecnv.c
+++ b/codecnv.c
@@ -370,6 +370,8 @@ void InitCodeConvInfo(CODECONVINFO *cInfo)
        cInfo->KanaProc = NULL;\r
        // UTF-8対応\r
        cInfo->EscUTF8Len = 0;\r
+       cInfo->EscFlush = NO;\r
+       cInfo->FlushProc = NULL;\r
        return;\r
 }\r
 \r
@@ -390,6 +392,13 @@ int FlushRestData(CODECONVINFO *cInfo)
 {\r
        char *Put;\r
 \r
+       // UTF-8対応\r
+       if(cInfo->FlushProc != NULL)\r
+       {\r
+               cInfo->EscFlush = YES;\r
+               return cInfo->FlushProc(cInfo);\r
+       }\r
+\r
        Put = cInfo->Buf;\r
 \r
        if(cInfo->KanaProc != NULL)\r
@@ -401,9 +410,6 @@ int FlushRestData(CODECONVINFO *cInfo)
                *Put++ = cInfo->EscCode[0];\r
        if(cInfo->EscProc == 2)\r
                *Put++ = cInfo->EscCode[1];\r
-       // UTF-8対応\r
-       memcpy(Put, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);\r
-       Put += cInfo->EscUTF8Len;\r
 \r
        cInfo->OutLen = Put - cInfo->Buf;\r
 \r
@@ -1481,12 +1487,63 @@ static int CheckOnEUC(uchar *Pos, uchar *Btm)
 *              くり返しフラグがYESの時は、cInfoの内容を変えずにもう一度呼ぶこと\r
 *----------------------------------------------------------------------------*/\r
 \r
+// UTF-8対応\r
+// UTF-8からShift_JISへの変換後のバイト列が確定可能な長さを変換後の長さで返す\r
+// バイナリ            UTF-8       戻り値 Shift_JIS\r
+// E3 81 82 E3 81 84   あい     -> 2      82 A0   あ+結合文字の先頭バイトの可能性(い゛等)\r
+// E3 81 82 E3 81      あ+E3 81 -> 0              結合文字の先頭バイトの可能性\r
+// E3 81 82 E3         あ+E3    -> 0              結合文字の先頭バイトの可能性\r
+// E3 81 82            あ       -> 0              結合文字の先頭バイトの可能性\r
+int ConvUTF8NtoSJIS_TruncateToDelimiter(char* pUTF8, int UTF8Length, int* pNewUTF8Length)\r
+{\r
+       int UTF16Length;\r
+       wchar_t* pUTF16;\r
+       int SJISLength;\r
+       int NewSJISLength;\r
+       int NewUTF16Length;\r
+       // UTF-8の場合、不完全な文字は常に変換されない\r
+       // バイナリ            UTF-8       バイナリ      UTF-16 LE\r
+       // E3 81 82 E3 81 84   あい     -> 42 30 44 30   あい\r
+       // E3 81 82 E3 81      あ+E3 81 -> 42 30         あ\r
+       // E3 81 82 E3         あ+E3    -> 42 30         あ\r
+       UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, NULL, 0);\r
+       if(!(pUTF16 = (wchar_t*)malloc(sizeof(wchar_t) * UTF16Length)))\r
+               return -1;\r
+       // Shift_JISへ変換した時に文字数が増減する位置がUnicode結合文字の区切り\r
+       UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, pUTF16, UTF16Length);\r
+       SJISLength = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
+       NewSJISLength = SJISLength;\r
+       while(UTF8Length > 0 && NewSJISLength >= SJISLength)\r
+       {\r
+               UTF8Length--;\r
+               UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, pUTF16, UTF16Length);\r
+               SJISLength = NewSJISLength;\r
+               NewSJISLength = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
+       }\r
+       free(pUTF16);\r
+       // UTF-16 LE変換した時に文字数が増減する位置がUTF-8の区切り\r
+       NewUTF16Length = UTF16Length;\r
+       while(UTF8Length > 0 && NewUTF16Length >= UTF16Length)\r
+       {\r
+               UTF8Length--;\r
+               UTF16Length = NewUTF16Length;\r
+               NewUTF16Length = MultiByteToWideChar(CP_UTF8, 0, pUTF8, UTF8Length, NULL, 0);\r
+       }\r
+       if(pNewUTF8Length)\r
+       {\r
+               if(UTF16Length > 0)\r
+                       UTF8Length++;\r
+               *pNewUTF8Length = UTF8Length;\r
+       }\r
+       return NewSJISLength;\r
+}\r
+\r
 int ConvUTF8NtoSJIS(CODECONVINFO *cInfo)\r
 {\r
        int Continue;\r
 \r
 //     char temp_string[2048];\r
-       int string_length;\r
+//     int string_length;\r
 \r
        // 大きいサイズに対応\r
        // 終端のNULLを含むバグを修正\r
@@ -1494,7 +1551,6 @@ int ConvUTF8NtoSJIS(CODECONVINFO *cInfo)
        char* pSrc;\r
        wchar_t* pUTF16;\r
        int UTF16Length;\r
-       int Count;\r
 \r
        Continue = NO;\r
 \r
@@ -1518,6 +1574,14 @@ int ConvUTF8NtoSJIS(CODECONVINFO *cInfo)
        memcpy(pSrc, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);\r
        memcpy(pSrc + cInfo->EscUTF8Len, cInfo->Str, sizeof(char) * cInfo->StrLen);\r
        *(pSrc + SrcLength) = '\0';\r
+       if(cInfo->EscFlush == NO)\r
+       {\r
+               // バッファに収まらないため変換文字数を半減\r
+               while(SrcLength > 0 && ConvUTF8NtoSJIS_TruncateToDelimiter(pSrc, SrcLength, &SrcLength) > cInfo->BufSize)\r
+               {\r
+                       SrcLength = SrcLength / 2;\r
+               }\r
+       }\r
        // UTF-8の場合、不完全な文字は常に変換されない\r
        UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pSrc, SrcLength, NULL, 0);\r
 \r
@@ -1559,7 +1623,6 @@ int ConvUTF8NtoSJIS(CODECONVINFO *cInfo)
 //                                             0,                              // 格納先サイズ\r
 //                                             NULL,NULL\r
 //                                     );\r
-       string_length = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
 \r
        // サイズ0 or 出力バッファサイズより大きい場合は、\r
        // cInfo->Bufの最初に'\0'を入れて、\r
@@ -1585,20 +1648,10 @@ int ConvUTF8NtoSJIS(CODECONVINFO *cInfo)
 //             NULL,NULL\r
 //     );\r
        cInfo->OutLen = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);\r
-       // バッファに収まらないため変換文字数を半減\r
-       while(cInfo->OutLen == 0 && UTF16Length > 0)\r
-       {\r
-               UTF16Length = UTF16Length / 2;\r
-               cInfo->OutLen = WideCharToMultiByte(CP_ACP, 0, pUTF16, UTF16Length, cInfo->Buf, cInfo->BufSize, NULL, NULL);\r
-       }\r
-       // 変換された元の文字列での文字数を取得\r
-       Count = WideCharToMultiByte(CP_UTF8, 0, pUTF16, UTF16Length, NULL, 0, NULL, NULL);\r
-       // 変換可能な残りの文字数を取得\r
-       UTF16Length = MultiByteToWideChar(CP_UTF8, 0, pSrc + Count, SrcLength - Count, NULL, 0);\r
-       cInfo->Str += Count - cInfo->EscUTF8Len;\r
-       cInfo->StrLen -= Count - cInfo->EscUTF8Len;\r
+       cInfo->Str += SrcLength - cInfo->EscUTF8Len;\r
+       cInfo->StrLen -= SrcLength - cInfo->EscUTF8Len;\r
        cInfo->EscUTF8Len = 0;\r
-       if(UTF16Length > 0)\r
+       if(ConvUTF8NtoSJIS_TruncateToDelimiter(cInfo->Str, cInfo->StrLen, NULL) > 0)\r
                Continue = YES;\r
        else\r
        {\r
@@ -1607,6 +1660,7 @@ int ConvUTF8NtoSJIS(CODECONVINFO *cInfo)
                cInfo->EscUTF8Len = cInfo->StrLen;\r
                cInfo->Str += cInfo->StrLen;\r
                cInfo->StrLen = 0;\r
+               cInfo->FlushProc = ConvUTF8NtoSJIS;\r
                Continue = NO;\r
        }\r
 \r
@@ -1664,25 +1718,28 @@ int ConvSJIStoUTF8N(CODECONVINFO *cInfo)
        memcpy(pSrc, cInfo->EscUTF8, sizeof(char) * cInfo->EscUTF8Len);\r
        memcpy(pSrc + cInfo->EscUTF8Len, cInfo->Str, sizeof(char) * cInfo->StrLen);\r
        *(pSrc + SrcLength) = '\0';\r
-       // Shift_JISの場合、不完全な文字でも変換されることがあるため、末尾の不完全な部分を削る\r
-       Count = 0;\r
-       while(Count < SrcLength)\r
+       if(cInfo->EscFlush == NO)\r
        {\r
-               if(((unsigned char)*(pSrc + Count) >= 0x81 && (unsigned char)*(pSrc + Count) <= 0x9f) || (unsigned char)*(pSrc + Count) >= 0xe0)\r
+               // Shift_JISの場合、不完全な文字でも変換されることがあるため、末尾の不完全な部分を削る\r
+               Count = 0;\r
+               while(Count < SrcLength)\r
                {\r
-                       if((unsigned char)*(pSrc + Count + 1) >= 0x40)\r
-                               Count += 2;\r
-                       else\r
+                       if(((unsigned char)*(pSrc + Count) >= 0x81 && (unsigned char)*(pSrc + Count) <= 0x9f) || (unsigned char)*(pSrc + Count) >= 0xe0)\r
                        {\r
-                               if(Count + 2 > SrcLength)\r
-                                       break;\r
-                               Count += 1;\r
+                               if((unsigned char)*(pSrc + Count + 1) >= 0x40)\r
+                                       Count += 2;\r
+                               else\r
+                               {\r
+                                       if(Count + 2 > SrcLength)\r
+                                               break;\r
+                                       Count += 1;\r
+                               }\r
                        }\r
+                       else\r
+                               Count += 1;\r
                }\r
-               else\r
-                       Count += 1;\r
+               SrcLength = Count;\r
        }\r
-       SrcLength = Count;\r
        UTF16Length = MultiByteToWideChar(CP_ACP, 0, pSrc, SrcLength, NULL, 0);\r
 \r
        // サイズ0 or バッファサイズより大きい場合は、\r
@@ -1779,6 +1836,7 @@ int ConvSJIStoUTF8N(CODECONVINFO *cInfo)
                cInfo->EscUTF8Len = cInfo->StrLen;\r
                cInfo->Str += cInfo->StrLen;\r
                cInfo->StrLen = 0;\r
+               cInfo->FlushProc = ConvSJIStoUTF8N;\r
                Continue = NO;\r
        }\r
 \r
index 6b16dd2..2519f43 100644 (file)
--- a/common.h
+++ b/common.h
@@ -1118,6 +1118,8 @@ typedef struct filelist {
 /*===== コード変換情報パケット =====*/\r
 \r
 typedef char * (*funcptr)(struct codeconvinfo *, char , char *);\r
+// UTF-8対応\r
+typedef int (*convptr)(struct codeconvinfo *);\r
 \r
 typedef struct codeconvinfo {\r
        char *Str;                      /* 文字列 */\r
@@ -1132,8 +1134,11 @@ typedef struct codeconvinfo {
        char KanjiFst;          /* 漢字コード1バイト目保存用 (内部処理用ワーク) */\r
        char KanaPrev;          /* 半角カタカナ保存用 (内部処理用ワーク) */\r
        funcptr KanaProc;       /* 半角カタカナ処理ルーチン (内部処理用ワーク) */\r
-       char EscUTF8[8];\r
-       int EscUTF8Len;\r
+       // UTF-8対応\r
+       char EscUTF8[16];       /* エスケープシーケンス文字数 (0~) (内部処理用ワーク) */\r
+       int EscUTF8Len;         /* エスケープシーケンス文字保存用 (内部処理用ワーク) */\r
+       int EscFlush;           /* 残り情報を出力 (YES/NO) */\r
+       convptr FlushProc;      /* 残り情報処理ルーチン (内部処理用ワーク) */\r
 } CODECONVINFO;\r
 \r
 \r
index c990d85..0760c53 100644 (file)
@@ -183,6 +183,9 @@ int MakeListWin(HWND hWnd, HINSTANCE hInst)
        LV_COLUMN LvCol;\r
        long Tmp;\r
 \r
+       // 変数が未初期化のバグ修正\r
+       memset(&LvCol, 0, sizeof(LV_COLUMN));\r
+\r
        /*===== ローカル側のリストビュー =====*/\r
 \r
        hWndListLocal = CreateWindowEx(/*WS_EX_STATICEDGE*/WS_EX_CLIENTEDGE,\r
@@ -1125,6 +1128,9 @@ void GetListTabWidth(void)
        LV_COLUMN LvCol;\r
        int i;\r
 \r
+       // 変数が未初期化のバグ修正\r
+       memset(&LvCol, 0, sizeof(LV_COLUMN));\r
+\r
        for(i = 0; i <= 3; i++)\r
        {\r
                LvCol.mask = LVCF_WIDTH;\r
@@ -1708,6 +1714,8 @@ static void AddListView(HWND hWnd, int Pos, char *Name, int Type, LONGLONG Size,
        if(Pos == -1)\r
                Pos = SendMessage(hWnd, LVM_GETITEMCOUNT, 0, 0);\r
 \r
+       // 変数が未初期化のバグ修正\r
+       memset(&LvItem, 0, sizeof(LV_ITEM));\r
        /* アイコン/ファイル名 */\r
        LvItem.mask = LVIF_TEXT | LVIF_IMAGE;\r
        LvItem.iItem = Pos;\r
@@ -1830,6 +1838,8 @@ void SelectFileInList(HWND hWnd, int Type)
        FILETIME Time2;\r
        int Find;\r
 \r
+       // 変数が未初期化のバグ修正\r
+       memset(&LvItem, 0, sizeof(LV_ITEM));\r
        Win = WIN_LOCAL;\r
        WinDst = WIN_REMOTE;\r
        if(hWnd == GetRemoteHwnd())\r
@@ -2010,6 +2020,8 @@ void FindFileInList(HWND hWnd, int Type)
        LV_ITEM LvItem;\r
        char *Title;\r
 \r
+       // 変数が未初期化のバグ修正\r
+       memset(&LvItem, 0, sizeof(LV_ITEM));\r
        Win = WIN_LOCAL;\r
        Title = MSGJPN050;\r
        if(hWnd == GetRemoteHwnd())\r
@@ -2291,6 +2303,8 @@ int FindNameNode(int Win, char *Name)
        if(Win == WIN_REMOTE)\r
                hWnd = GetRemoteHwnd();\r
 \r
+       // 変数が未初期化のバグ修正\r
+       memset(&FindInfo, 0, sizeof(LV_FINDINFO));\r
        FindInfo.flags = LVFI_STRING;\r
        FindInfo.psz = Name;\r
        return(SendMessage(hWnd, LVM_FINDITEM, -1, (LPARAM)&FindInfo));\r
@@ -2318,6 +2332,8 @@ void GetNodeName(int Win, int Pos, char *Buf, int Max)
        if(Win == WIN_REMOTE)\r
                hWnd = GetRemoteHwnd();\r
 \r
+       // 変数が未初期化のバグ修正\r
+       memset(&LvItem, 0, sizeof(LV_ITEM));\r
        LvItem.mask = LVIF_TEXT;\r
        LvItem.iItem = Pos;\r
        LvItem.iSubItem = 0;\r
@@ -2351,6 +2367,8 @@ int GetNodeTime(int Win, int Pos, FILETIME *Buf)
        if(Win == WIN_REMOTE)\r
                hWnd = GetRemoteHwnd();\r
 \r
+       // 変数が未初期化のバグ修正\r
+       memset(&LvItem, 0, sizeof(LV_ITEM));\r
        LvItem.mask = LVIF_TEXT;\r
        LvItem.iItem = Pos;\r
        LvItem.iSubItem = 1;\r
@@ -2385,6 +2403,8 @@ int GetNodeSize(int Win, int Pos, LONGLONG *Buf)
        if(Win == WIN_REMOTE)\r
                hWnd = GetRemoteHwnd();\r
 \r
+       // 変数が未初期化のバグ修正\r
+       memset(&LvItem, 0, sizeof(LV_ITEM));\r
        LvItem.mask = LVIF_TEXT;\r
        LvItem.iItem = Pos;\r
        LvItem.iSubItem = 2;\r
@@ -2432,6 +2452,8 @@ int GetNodeAttr(int Win, int Pos, int *Buf)
        Ret = NO;\r
        if(Win == WIN_REMOTE)\r
        {\r
+               // 変数が未初期化のバグ修正\r
+               memset(&LvItem, 0, sizeof(LV_ITEM));\r
                LvItem.mask = LVIF_TEXT;\r
                LvItem.iItem = Pos;\r
 #if defined(HAVE_TANDEM)\r
@@ -2479,6 +2501,8 @@ int GetNodeType(int Win, int Pos)
        if(Win == WIN_REMOTE)\r
                hWnd = GetRemoteHwnd();\r
 \r
+       // 変数が未初期化のバグ修正\r
+       memset(&LvItem, 0, sizeof(LV_ITEM));\r
        LvItem.mask = LVIF_TEXT;\r
        LvItem.iItem = Pos;\r
        LvItem.iSubItem = 2;\r
@@ -2516,6 +2540,8 @@ void GetNodeOwner(int Win, int Pos, char *Buf, int Max)
        strcpy(Buf, "");\r
        if(Win == WIN_REMOTE)\r
        {\r
+               // 変数が未初期化のバグ修正\r
+               memset(&LvItem, 0, sizeof(LV_ITEM));\r
                LvItem.mask = LVIF_TEXT;\r
                LvItem.iItem = Pos;\r
                LvItem.iSubItem = 5;\r