【バグ】WideCharToMultiByte の動作がOSごとに違う!その1

Windows 2000でWideCharToMultiByte関数を使うと、ISO-2022-JPのバイト数を間違う という記事を見かけたので、調べてみたところ、もっと深い違いがあったのでまとめてみました。


使ったのは次のようなコード

#include "stdafx.h"
#include <stdio.h>
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow )
{
//  50220   |JIS
//  50221   |JIS(Allow 1 byte Kana)
//  50222   |JIS(Allow 1 byte Kana)(SO/SI)
  int cp,r0,r2,r3;
  char uni[256]="W\x00i\x00n\x00\x12\xff\x2b\xff",str[512];
// Win2K
  char uni2[256]="\x0a\xff\x73\xff\x68\xff\x9d\xff\x32\x6b";
//←最後ミスってます
// *ウィン2k
  OSVERSIONINFO OS;
  OS.dwOSVersionInfoSize=sizeof(OS);
  GetVersionEx(&OS);
  cp = 50222;
  r0= WideCharToMultiByte(cp, 0, (wchar_t*)uni, 5, NULL, 0, NULL, NULL);
  cp = 50221;
  r2 = WideCharToMultiByte(cp, 0, (wchar_t*)uni2, 6, NULL, 0, NULL, NULL);
  cp = 50220;
  r3 = WideCharToMultiByte(cp, 0, (wchar_t*)uni2, 6, NULL, 0, NULL, NULL);
  wsprintf(str,"OS: %d.%d(Build:%d)\r\n1:%d 2:%d 3:%d",
OS.dwMajorVersion,OS.dwMinorVersion,OS.dwBuildNumber,r0,r2,r3);
  MessageBox(0,str,"Result",0);
  return 0;
}

まず結果から…。
wcmc1
Vista

wcmc2
Windows HomeServer(XPが手元に無いので(^^;)

wcmc3
Windows 2000

ちょっとちょっと、全部違うじゃないですか!(^^;

Windows XP系とVistaの違いは、JIS文字列が全角で終わった場合に、ESCシーケンスで半角に戻す処理がどうも入るみたいで、3バイト多くなるようです。
Windows2000の場合はエスケープシーケンスの文字数を返さないのでこうなってしまう模様。それぞれ、3x1、3x3、3x2バイト少なくなってしまった。

これは、kernel32.dll のバグですねぇ。KDWでfix入れてみるかな?

関連サイト:
Windows 2000でWideCharToMultiByte関数を使うと、ISO-2022-JPのバイト数を間違う | 山本隆の開発日誌
ScanNetSecurity - Microsoft Windows 2000 SP4のWideCharToMultiByteでバッファオーバーフローが見つかる

おすすめ

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です