Windowsでstrlcpy、strlcatを使う(MinGW)

strlcpy, strlcat

BSD系で実装されているstrncpy, strncatのセキュア版。BSDライセンス
末尾に'\0'が必ず付くよう保証されている。
例えば以下のような書き方ができ、末尾は必ず'\0'で終端する。

    char buf[8];
    strlcpy(buf, "123456789", sizeof(buf));
    strlcat(buf, "abcdefghi", sizeof(buf));

既存のstrncpy, strncatでは末尾が'\0'で終端しないので
あふれるときはとても危険である。
Linux(Ubuntu)系でstrlcpy,strlcatを使うには以下のように別途installが必要。

$ sudo apt-get install libbsd-dev

Windows系ではGNUWinにlibgw32というパッケージが用意されている。
http://gnuwin32.sourceforge.net/packages/libgw32c.htm
ただしGPLライセンスに引っかかるのでMinGWを使って自前の
ライブラリを作ってみる。

MinGWで自前のlibraryを作る(libstrllib.a)

  • ソースをOpenBSDやGNUWinから取得する
    http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/string/
    http://gnuwin32.sourceforge.net/packages/libgw32c.htm
    strlcpy.c
    strlcpy.h
    strlcat.c
    strlcat.h
    $ gcc -c strlcpy.c strlcat.c
    strlcpy.o, strlcat.oができる。
  • libstrllib.aという名前でライブラリを作る
    $ ar rcs libstrllib.a strlcpy.o strlcat.o
  • できあがったライブラリとヘッダファイルを所定の場所にコピーする
    strlcpy.h strlcat.h -> \MinGW\include
    libstrllib.a -> \MinGW\lib

これで準備は完了。

自分のプログラムと自作ライブラリをリンクする

    $ gcc test.c -lstrllib
    静的にリンクされるので別途DLLを必要としない。
    Linuxでは以下のようにする。
    $ gcc test.c -lbsd

sample code

#include <stdio.h>
#if !defined UNIX
#include <strlcpy.h>
#include <strlcat.h>
#else   /* UNIX */
#include <bsd/string.h>  /* Linux */
#endif  /* UNIX */

main()
{
    char buf[8];
    strlcpy(buf, "123456789", sizeof(buf));
    strlcat(buf, "abcdefghi", sizeof(buf));
    printf("buf = %s\n", buf);
}

実行結果
buf = 1234567

Visual C++でもstrlcat, strlcpyが使えるようにしてみるか

Visual C++ではstrncat_s, strncpy_sがセキュア版として用意されている。
しかし、他のプラットフォームに移植しづらいから使いたくない。
ということでVisual C++でもstrlcpy, strlcatが使えるようライブラリ化してみる。
Visual C++コマンドライン版(cl.exe)を使っている限りではgccライクに使えてあまり悩むことはない(かな?)。

  • DOS窓(command prompt)を開き、ソースのある場所へ移動
  • "C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"を実行して環境変数等を整える。よく使うならこのBATファイルをどこかPATHの張ってあるところにcopyしておく。
  • 以下のようにcompileする
    dos> cl /W4 /c strlcat.c strlcpy.c
    strlcat.obj, strlcpy.objができる
  • 次にライブラリ化する
    dos> lib /OUT:strllib.lib strlcat.obj strlcpy.obj
    これによりstrllib.libができる
  • 所定の場所にファイルをコピーする
    strlcat.h strlcpy.h -> C:\Program Files\Microsoft Visual Studio 10.0\VC\include
    strllib.lib -> C:\Program Files\Microsoft Visual Studio 10.0\VC\lib
  • 自分のプログラムとリンクするには以下のように指定する
    dos> cl /W4 test.c strllib.lib