[ruby-dev:31776] Re: 1.9 on OpenBSD

From: Nobuyoshi Nakada <nobu@...>
Date: 2007-09-12 02:18:22 UTC
List: ruby-dev #31776
なかだです。

At Wed, 12 Sep 2007 07:10:43 +0900,
SASADA Koichi wrote in [ruby-dev:31775]:
>  OpenBSD 上で 1.9 をコンパイルしたら,こんな警告が出ました.どうし
> たもんでしょう.

OpenBSDが偏執的というだけのような。

> gcc -g -O2 -L.  -Wl,-E   main.o  libruby-static.a -lpthread -lm   -o
> miniruby
> libruby-static.a(io.o)(.text+0x3e12): In function `rb_io_s_sysopen':
> ../trunk/io.c:3459: warning: strcpy() is almost always misused,
> please use strlcpy()

ここでは必要な長さを割り当ててからコピーしているので、strcpyでも
問題はないはずです。むしろ問題はその前のallocaにあって、容易に
stack overflowを起こせます。

  $ ruby19 -e 'IO.sysopen("x"*10_000_000)'
  セグメンテーション違反です (core dumped)

> libruby-static.a(marshal.o)(.text+0x694): In function `w_float':
> ../trunk/marshal.c:329: warning: sprintf() is often misused, please
> use snprintf()

こちらは内部で上限の決まっているものなので、とんでもなくdoubleの
桁数の大きい(doubleが300bit以上あるような)環境でない限り問題はな
いはずです。

> libruby-static.a(parse.o)(.text+0xcff8): In function `rb_id2str':
> ../trunk/parse.y:8563: warning: strcat() is almost always misused,
> please use strlcat()

これもrb_io_s_sysopenと同様でしょう。

ちなみに、rb_str_cat()などの引数にあるchar*のエンコーディングは
どうなるんでしょうか。ASCII?


Index: io.c
===================================================================
--- io.c	(revision 13429)
+++ io.c	(working copy)
@@ -3456,6 +3456,6 @@ rb_io_s_sysopen(int argc, VALUE *argv)
     else             fmode = NUM2INT(perm);
 
-    path = ALLOCA_N(char, strlen(RSTRING_PTR(fname))+1);
-    strcpy(path, RSTRING_PTR(fname));
+    RB_GC_GUARD(fname) = rb_str_new4(fname);
+    path = RSTRING_PTR(fname);
     fd = rb_sysopen(path, flags, fmode);
     return INT2NUM(fd);
Index: marshal.c
===================================================================
--- marshal.c	(revision 13429)
+++ marshal.c	(working copy)
@@ -310,5 +310,5 @@ static void
 w_float(double d, struct dump_arg *arg)
 {
-    char buf[100];
+    char buf[FLOAT_DIG + (DECIMAL_MANT + 7) / 8 + 10];
 
     if (isinf(d)) {
@@ -327,5 +327,5 @@ w_float(double d, struct dump_arg *arg)
 
 	/* xxx: should not use system's sprintf(3) */
-	sprintf(buf, "%.*g", FLOAT_DIG, d);
+	snprintf(buf, sizeof(buf), "%.*g", FLOAT_DIG, d);
 	len = strlen(buf);
 	w_bytes(buf, len + save_mantissa(d, buf + len), arg);
Index: parse.y
===================================================================
--- parse.y	(revision 13429)
+++ parse.y	(working copy)
@@ -8554,19 +8554,15 @@ rb_id2str(ID id)
     if (is_attrset_id(id)) {
 	ID id2 = (id & ~ID_SCOPE_MASK) | ID_LOCAL;
+	VALUE str;
 
-      again:
-	name = rb_id2name(id2);
-	if (name) {
-	    char *buf = ALLOCA_N(char, strlen(name)+2);
-
-	    strcpy(buf, name);
-	    strcat(buf, "=");
-	    rb_intern(buf);
-	    return rb_id2str(id);
-	}
-	if (is_local_id(id2)) {
+	while (!(str = rb_id2str(id2))) {
+	    if (!is_local_id(id2)) return 0;
 	    id2 = (id & ~ID_SCOPE_MASK) | ID_CONST;
-	    goto again;
 	}
+	str = rb_str_dup(str);
+	rb_str_cat(buf, "=", 1);
+	rb_intern_str(str);
+	if (st_lookup(global_symbols.id_str, id, &data))
+	    return (VALUE)data;
     }
     return 0;


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread