yas@is.tsukuba.ac.jp (Yasushi Shinjo) writes:

> >   strncpy(dest, src, n) は n > strlen(src) の場合に
> >   dest+strlen(src) 以降に nul を埋めるだけで、
> >   strlcpy の場合はこれに加え、n <= strlen(src) の場合も
> >   dest+n に nul を埋めるので、バッファ・オーバーフローを防ぐ
> >   には strlcpy のほうがベターである
> > 
> > ということをおっしゃっているのでしょうか?

結局↑はどうなんでしょう?

新城さんがおっしゃる「誤用」というのをはっきり知りたいと思っ
ていますので教えてください。しつこくてすみません。

> > 私は strcpy や strcat を好んで使いますし、これからも使ってい
> > くと思います。strncpy などは n なしに比べてだいぶ遅いんです
> > もん。
> 
> 速度を気にする時代じゃないと思いますよ。

ですね。たいていは気分の問題だと思います。中にはほんとに必要
な場合もあることにはあると思いますが。

> > たぶん strcpy/strcat を使わないように指導するのではなく、そ
> > れらの関数の危険性と、安全に使うための方法を教えたほうがいい
> > のではないでしょうか?
> 
> 人間は間違える。それが前提です。その前提で安全に使う方法とは、
> どういう方法ですか。是非とも教えてください。

こう聞かれると、そんなものはありませんとしか答えられません
ねぇ。strlcpy なんかでも使いかたを間違えればバッファオーバー
フローも起りえますし。

> その方法と、strlcpy()、snprintf() を使う方法との比較しましょう。

一概にどの方法がいいということは言えないと思うんです。
strlcpy を使ったほうがいい場合もありますし、strcpy で十分な
場合もあると思うのですが、その判断を行うには、それらの関数の
仕様の理解と、想定される危険性についての知識が必要だと思うの
です。

というのを踏まえて、たとえばですが、こんなのでも多くのケース
では十分安全だと思います。

void copy(char *dst, char *src, size_t n)
{
  char *b;
  size_t l = strlen(src);
  if (!(b = (char*)malloc(l + 1)))
    abort();
  strcpy(b, src);
  if (l > n)
    b[n] = '\0';
  strcpy(dst, b);
  free(b);
}

これはある程度汎用的に使えますが、局所的な用途では、

  src[MAX] = '\0';
  strcpy(dst, src);

で事足りてしまうケースもよくあります。

-- 
01/12 10:51頃
水戸