From: GOTOU Yuuzou Date: 2003-04-07T14:55:22+09:00 Subject: [ruby-dev:19965] unpack_sockaddr_in: sockaddr_in size differs Socket::unpack_sockaddr_in が struct sockaddr_in6 の場合にエラー になります。 % ruby -v ruby 1.8.0 (2003-04-04) [i386-netbsd] % ruby -r socket -e 'p Socket::unpack_sockaddr_in(Socket::pack_sockaddr_in(0,"::"))' -e:1:in `unpack_sockaddr_in': sockaddr_in size differs - 28 required; 16 given (TypeError) from -e:1 応急処置でパッチを作ったので添付してみます。 サイズのチェックが甘いですが、sockaddr_in が詰まった長めのバッ ファを扱うプログラムを書いていたので、長い分にはエラーにならな いほうが嬉しいと思います。 -- ごとうゆうぞう diff -u -p -r1.91 socket.c --- ext/socket/socket.c 16 Jan 2003 07:38:40 -0000 1.91 +++ ext/socket/socket.c 7 Apr 2003 05:32:08 -0000 @@ -2324,14 +2324,24 @@ static VALUE sock_s_unpack_sockaddr_in(self, addr) VALUE self, addr; { + struct sockaddr_storage buf; + size_t len; struct sockaddr_in * sockaddr; VALUE host; - sockaddr = (struct sockaddr_in*)StringValuePtr(addr); - if (RSTRING(addr)->len != sizeof(struct sockaddr_in)) { - rb_raise(rb_eTypeError, "sockaddr_in size differs - %ld required; %d given", + StringValue(addr); + if (RSTRING(addr)->len < sizeof(struct sockaddr_in)) { + rb_raise(rb_eTypeError, + "sockaddr_in size differs - %ld required; %d given", RSTRING(addr)->len, sizeof(struct sockaddr_in)); } + if(RSTRING(addr)->len < sizeof(struct sockaddr_storage)) + len = RSTRING(addr)->len; + else + len = sizeof(struct sockaddr_storage); + sockaddr = (struct sockaddr_in*)&buf; + memset(sockaddr, 0, sizeof(struct sockaddr_storage)); + memcpy(sockaddr, RSTRING(addr)->ptr, len); host = mkipaddr((struct sockaddr*)sockaddr); OBJ_INFECT(host, addr); return rb_assoc_new(INT2NUM(ntohs(sockaddr->sin_port)), host);