Issue #6479 has been reported by kachick (Kenichi Kamiya). ---------------------------------------- Bug #6479: ipaddr.rbの受け付ける書式が、プラットフォームによって異なる https://bugs.ruby-lang.org/issues/6479 Author: kachick (Kenichi Kamiya) Status: Open Priority: Normal Assignee: Category: lib Target version: 1.9.3 ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] # 状況 標準添付ライブラリの ipaddr.rb に於いて、アドレス書式チェック時の厳しさがプラットフォームによって異なるよう感じました。 IPv4で気がついた限りですが、次の2点でWindowsだと常に例外を吐き、Linuxだと書式によっては(自分にとって)想定し難い値を返します。 * 0埋めを含んだ場合 * 改行文字を含んだ場合 動作例を載せます。 ## 共通 require 'ipaddr' p IPAddr.new("11.22.33.45") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> ## Windows(7) / ruby 1.9.3p194 (2012-04-20) [i386-mingw32] # 以下全てで、同じ例外を吐きます。 p IPAddr.new("011.22.33.45") p IPAddr.new("011.0022.00033.000045") p IPAddr.new("011.0022.00033.000045\n") p IPAddr.new("011.0022.00033.000045\nfoo32/0024/bar \n/foobar ") p IPAddr.new("011.0022.00033.000045\n056.0067.00078.00089\nfoo32/0024/bar \n/foobar ") # 例外 ArgumentError: invalid address from C:/Ruby193/lib/ruby/1.9.1/ipaddr.rb:496:in `rescue in initialize' ## Linux(Mint12) / ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] # Windowsの際と同じ引数に対して、一つも例外を吐きません p IPAddr.new("011.22.33.45") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045\n") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045\nfoo32/0024/bar \n/foobar ") #=> #<IPAddr: IPv4:11.22.33.0/255.255.255.0> p IPAddr.new("011.0022.00033.000045\n056.0067.00078.00089\nfoo32/0024/bar \n/foobar ") #=> #<IPAddr: IPv4:45.67.78.0/255.255.255.0> # 希望 Windows環境下の例にみるよう、上記全てのパターンで例外を吐いてくれる方が自然に感じました。 特にLinux上での0埋めに関しては、桁数に制限が見られ無い点と、IPSocket.getaddress(8進数?)と返す値の異なってしまう点が気になります。 ## Linux(Mint12) / ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] require 'socket' p IPSocket.getaddress("011.0022.00033.000045") #=> "9.18.27.37" # 参考 ipaddr.rbを自分なりに読んでみた限り、次の要素に起因するのではないかとあたりをつけてみましたが・・・確信はありません。 * 全体的に、チェック用正規表現のメタ文字へ \A\z を使わず、 \A\Z や ^$ で括っていること * #initialize で、 IPSocket.getaddress が例外を返すかどうかに、正常異常の判断を大きく委ねていること * #in_addr で、1つのオクテットを \d+ のみでキャプチャしていること とりあえず、#in_addrのみを次のように上書きした際、Windowsと同様に動作することまでは確認できました。 require 'ipaddr' class IPAddr private remove_method :in_addr def in_addr(addr) if addr =~ /\A(?:(?:0|[1-9]\d{0,2})\.){3}(?:0|[1-9]\d{0,2})\z/ return addr.split('.').inject(0) { |i, s| n = s.to_i raise ArgumentError, 'invalid address' unless n <= 255 i << 8 | n } end return nil end end
on 2012-05-22 19:50
on 2012-05-23 09:17
Issue #6479 has been updated by knu (Akinori MUSHA). Status changed from Open to Assigned Assignee set to knu (Akinori MUSHA) ---------------------------------------- Bug #6479: ipaddr.rbの受け付ける書式が、プラットフォームによって異なる https://bugs.ruby-lang.org/issues/6479#change-26781 Author: kachick (Kenichi Kamiya) Status: Assigned Priority: Normal Assignee: knu (Akinori MUSHA) Category: lib Target version: 1.9.3 ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] # 状況 標準添付ライブラリの ipaddr.rb に於いて、アドレス書式チェック時の厳しさがプラットフォームによって異なるよう感じました。 IPv4で気がついた限りですが、次の2点でWindowsだと常に例外を吐き、Linuxだと書式によっては(自分にとって)想定し難い値を返します。 * 0埋めを含んだ場合 * 改行文字を含んだ場合 動作例を載せます。 ## 共通 require 'ipaddr' p IPAddr.new("11.22.33.45") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> ## Windows(7) / ruby 1.9.3p194 (2012-04-20) [i386-mingw32] # 以下全てで、同じ例外を吐きます。 p IPAddr.new("011.22.33.45") p IPAddr.new("011.0022.00033.000045") p IPAddr.new("011.0022.00033.000045\n") p IPAddr.new("011.0022.00033.000045\nfoo32/0024/bar \n/foobar ") p IPAddr.new("011.0022.00033.000045\n056.0067.00078.00089\nfoo32/0024/bar \n/foobar ") # 例外 ArgumentError: invalid address from C:/Ruby193/lib/ruby/1.9.1/ipaddr.rb:496:in `rescue in initialize' ## Linux(Mint12) / ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] # Windowsの際と同じ引数に対して、一つも例外を吐きません p IPAddr.new("011.22.33.45") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045\n") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045\nfoo32/0024/bar \n/foobar ") #=> #<IPAddr: IPv4:11.22.33.0/255.255.255.0> p IPAddr.new("011.0022.00033.000045\n056.0067.00078.00089\nfoo32/0024/bar \n/foobar ") #=> #<IPAddr: IPv4:45.67.78.0/255.255.255.0> # 希望 Windows環境下の例にみるよう、上記全てのパターンで例外を吐いてくれる方が自然に感じました。 特にLinux上での0埋めに関しては、桁数に制限が見られ無い点と、IPSocket.getaddress(8進数?)と返す値の異なってしまう点が気になります。 ## Linux(Mint12) / ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] require 'socket' p IPSocket.getaddress("011.0022.00033.000045") #=> "9.18.27.37" # 参考 ipaddr.rbを自分なりに読んでみた限り、次の要素に起因するのではないかとあたりをつけてみましたが・・・確信はありません。 * 全体的に、チェック用正規表現のメタ文字へ \A\z を使わず、 \A\Z や ^$ で括っていること * #initialize で、 IPSocket.getaddress が例外を返すかどうかに、正常異常の判断を大きく委ねていること * #in_addr で、1つのオクテットを \d+ のみでキャプチャしていること とりあえず、#in_addrのみを次のように上書きした際、Windowsと同様に動作することまでは確認できました。 require 'ipaddr' class IPAddr private remove_method :in_addr def in_addr(addr) if addr =~ /\A(?:(?:0|[1-9]\d{0,2})\.){3}(?:0|[1-9]\d{0,2})\z/ return addr.split('.').inject(0) { |i, s| n = s.to_i raise ArgumentError, 'invalid address' unless n <= 255 i << 8 | n } end return nil end end
on 2012-05-23 10:23
$B$3$s$K$A$O!"$J$+$`$i(B($B$&(B)$B$G$9!#(B
In message "[ruby-dev:45671] [ruby-trunk - Bug #6479][Assigned]
ipaddr.rb$B$N<u$1IU$1$k=q<0$,!"%W%i%C%H%U%)!<%`$K$h$C$F0[$J$k(B"
on May.23,2012 16:16:40, <knu@ruby-lang.org> wrote:
>
$B$H$j$"$($:!"(B#in_addr$B$N$_$r<!$N$h$&$K>e=q$-$7$?:]!"(BWindows$B$HF1MM$KF0:n$9$k$3$H$^$G$O3NG'$G$-$^$7$?!#(B
Socket::AF_INET6$B$,$J$$>l9g$K(BIPSocket.getaddress$B$r>e=q$-$7$F$$(B
$B$k%3!<%I$,(Bipaddr.rb$B$NKAF,$K$"$k$H;W$$$^$9$N$G!"%W%i%C%H%U%)!<(B
$B%`Ds6!$N$=$l$,?.MQ$G$-$J$$$J$i$3$C$A$r>o$KM-8z$K$9$k$N$b$"$j(B
$B$+$b$7$l$^$;$s!#(B
Windows$B$@$H$?$V$s$=$l$r;H$C$F$k$s$@$H;W$$$^$9!#(B
$B$=$l$G$O!#(B
on 2012-05-24 17:05
$B$3$s$P$s$O!"$+$_$d$G$9!#(B $B$4JV?.M-Fq$&$4$6$$$^$9!#(B 2012$BG/(B5$B7n(B23$BF|(B 17:23 U.Nakamura <usa@garbagecollect.jp>: > Socket::AF_INET6$B$,$J$$>l9g$K(BIPSocket.getaddress$B$r>e=q$-$7$F$$(B > $B$k%3!<%I$,(Bipaddr.rb$B$NKAF,$K$"$k$H;W$$$^$9$N$G!"%W%i%C%H%U%)!<(B > $B%`Ds6!$N$=$l$,?.MQ$G$-$J$$$J$i$3$C$A$r>o$KM-8z$K$9$k$N$b$"$j(B > $B$+$b$7$l$^$;$s!#(B $B3N$+$K!"$I$N4D6-$G$b$3$NJU$N%A%'%C%/$r7PM3$9$k$h$&$K$J$l$P(B $B0B?446$,A}$9$H;W$$$^$9!#(B $BDI2C$5$l$k(B IPSocket.valid_v4? $B$@$H(B $B!"!V(B0$BKd$a$O(B3$B7e$^$G5vMF!W(B $B!VKvHx$N2~9TJ8;z$O5vMF!W(B $B$K$J$k46$8$G$7$g$&$+(B > Windows$B$@$H$?$V$s$=$l$r;H$C$F$k$s$@$H;W$$$^$9!#(B $B$?$@!"8=:_(BWindows$B>e$G$3$l$i$N%Q%?!<%s$rCF$$$F$/$l$F$$$k$N$H!"(B ipaddr$B%i%$%V%i%j$N(B require$BA0$G$b!"(B Socket::AF_INET6 $B$NDj5A$5$l$F$$$k$3$H$,5$$K$J$j$^$7$?!#(B ## Windows(7) / ruby 1.9.3p194 (2012-04-20) [i386-mingw32] require 'socket' Socket.const_defined? :AF_INET6 #=> true Socket::AF_INET6 #=> 23 $B2?$+:,K\E*$K4*0c$$$7$F$$$k$h$&$G$"$l$P?=$7Lu$"$j$^$;$s!#(B
on 2012-05-25 07:00
At Wed, 23 May 2012 17:23:23 +0900, U.Nakamura wrote: > In message "[ruby-dev:45671] [ruby-trunk - Bug #6479][Assigned] ipaddr.rb$B$N<u$1IU$1$k=q<0$,!"%W%i%C%H%U%)!<%`$K$h$C$F0[$J$k(B" > on May.23,2012 16:16:40, <knu@ruby-lang.org> wrote: > > $B$H$j$"$($:!"(B#in_addr$B$N$_$r<!$N$h$&$K>e=q$-$7$?:]!"(BWindows$B$HF1MM$KF0:n$9$k$3$H$^$G$O3NG'$G$-$^$7$?!#(B > > Socket::AF_INET6$B$,$J$$>l9g$K(BIPSocket.getaddress$B$r>e=q$-$7$F$$(B > $B$k%3!<%I$,(Bipaddr.rb$B$NKAF,$K$"$k$H;W$$$^$9$N$G!"%W%i%C%H%U%)!<(B > $B%`Ds6!$N$=$l$,?.MQ$G$-$J$$$J$i$3$C$A$r>o$KM-8z$K$9$k$N$b$"$j(B > $B$+$b$7$l$^$;$s!#(B > Windows$B$@$H$?$V$s$=$l$r;H$C$F$k$s$@$H;W$$$^$9!#(B IPAddr.new $B$K$*$1$k(B IPSocket.getaddress $B$N8F$S=P$7$G$9$,!"?dB,$9$k$K!"(B Socket.getaddrinfo(..., Socket::AI_NUMERICHOST) $B$,0U?^DL$jF0$$$F$/$l$J(B $B$+$C$?$N$G(B IPSocket.getaddress $B$K=q$-49$($?$,!"A[Dj!J(Bsocket $B$N(BIPv6$BBP1~(B $B$O40N;$7$F$$$?$N$G!D!K$KH?$7$F$3$$$D$N(BIPv6$B%"%I%l%9BP1~$,%W%i%C%H%U%)!<(B $B%`0MB8$@$C$?$H$$$&$3$H$G$O$J$$$+$H;W$$$^$9!#(B $B$$$:$l$K$7$F$b!"(B IPAddr $B%l%Y%k$G$N%W%i%C%H%U%)!<%`0MB8@-$OK>$^$7$/$J$$(B $B$N$G!"$3$l$r8F$VA0$K8!::$*$h$S@55,2=!J%<%mKd$aGS=|Ey!K$9$k$h$&$K$7$^$9!#(B $B$J$*!"(B IPSocket.valid*? $B>r7oIU$-$GI=$K=P$k$N$OJQ$J$N$G$3$3$O(B private $B$K(B $B$7!"(B IPSocket.getaddress $B$N>e=q$-$K$D$$$F$b(B AF_INET6 $B$,$J$$>l9g$N(B IPv6$B%"%I%l%9BP1~$NIU2CDxEY$K;_$a$?$$$H;W$$$^$9!#(B
on 2012-05-25 08:35
$B$3$s$K$A$O!"$J$+$`$i(B($B$&(B)$B$G$9!#(B
In message "[ruby-dev:45678] Re: [ruby-trunk - Bug #6479][Assigned]
ipaddr.rb$B$N<u$1IU$1$k=q<0$,!"%W%i%C%H%U%)!<%`$K$h$C$F0[$J$k(B"
on May.25,2012 00:03:08, <kachick1@gmail.com> wrote:
> > Windows$B$@$H$?$V$s$=$l$r;H$C$F$k$s$@$H;W$$$^$9!#(B
>
> $B$?$@!"8=:_(BWindows$B>e$G$3$l$i$N%Q%?!<%s$rCF$$$F$/$l$F$$$k$N$H!"(B
> ipaddr$B%i%$%V%i%j$N(B require$BA0$G$b!"(B
> Socket::AF_INET6 $B$NDj5A$5$l$F$$$k$3$H$,5$$K$J$j$^$7$?!#(B
$B$"!<!"(BWindows$B$N(BIPv6$B%5%]!<%H$O:#$OM-8z$J$s$G$7$?$C$1!#(B
# $B<+J,$G$d$C$?$N$KK:$l$F$$$k!#(B
> $B2?$+:,K\E*$K4*0c$$$7$F$$$k$h$&$G$"$l$P?=$7Lu$"$j$^$;$s!#(B
$B$J$N$G4*0c$$$7$F$$$?$N$O;d$N$h$&$G$9!#(B
$B$=$l$G$O!#(B
on 2012-05-30 05:33
Issue #6479 has been updated by knu (Akinori MUSHA). 本件の実装の大枠はもうできていて、あとはどういう表記を認めるかというところで諸方面に確認中ですが、ゼロ埋めについては不許可にしたいと思うようになりました。 というのもアドレスのパースに用いられるCの inet_addr() の仕様を見ると、ドット区切りの各オクテットが0で始まるときは8進数として扱うべしとあり、一方でゼロ埋めの十進3桁固定方式も入力フォーム等で見られるため、ライブラリ側ではいずれとも判断しかねるからです。 cf. http://pubs.opengroup.org/onlinepubs/009696799/fun... 従来もWindowsではエラーになっていたことですし、ここで禁止とするのもありかなと思います。 なお、あとは x:x:x:x:x:x:d.d.d.d 形式で今までは意図せずエラーとなっていた部分について仕様を詰めており、これが詰まり次第commitおよびbackportする予定です。もうしばらくお待ちください。 ---------------------------------------- Bug #6479: ipaddr.rbの受け付ける書式が、プラットフォームによって異なる https://bugs.ruby-lang.org/issues/6479#change-26899 Author: kachick (Kenichi Kamiya) Status: Assigned Priority: Normal Assignee: knu (Akinori MUSHA) Category: lib Target version: 1.9.3 ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] # 状況 標準添付ライブラリの ipaddr.rb に於いて、アドレス書式チェック時の厳しさがプラットフォームによって異なるよう感じました。 IPv4で気がついた限りですが、次の2点でWindowsだと常に例外を吐き、Linuxだと書式によっては(自分にとって)想定し難い値を返します。 * 0埋めを含んだ場合 * 改行文字を含んだ場合 動作例を載せます。 ## 共通 require 'ipaddr' p IPAddr.new("11.22.33.45") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> ## Windows(7) / ruby 1.9.3p194 (2012-04-20) [i386-mingw32] # 以下全てで、同じ例外を吐きます。 p IPAddr.new("011.22.33.45") p IPAddr.new("011.0022.00033.000045") p IPAddr.new("011.0022.00033.000045\n") p IPAddr.new("011.0022.00033.000045\nfoo32/0024/bar \n/foobar ") p IPAddr.new("011.0022.00033.000045\n056.0067.00078.00089\nfoo32/0024/bar \n/foobar ") # 例外 ArgumentError: invalid address from C:/Ruby193/lib/ruby/1.9.1/ipaddr.rb:496:in `rescue in initialize' ## Linux(Mint12) / ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] # Windowsの際と同じ引数に対して、一つも例外を吐きません p IPAddr.new("011.22.33.45") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045\n") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045\nfoo32/0024/bar \n/foobar ") #=> #<IPAddr: IPv4:11.22.33.0/255.255.255.0> p IPAddr.new("011.0022.00033.000045\n056.0067.00078.00089\nfoo32/0024/bar \n/foobar ") #=> #<IPAddr: IPv4:45.67.78.0/255.255.255.0> # 希望 Windows環境下の例にみるよう、上記全てのパターンで例外を吐いてくれる方が自然に感じました。 特にLinux上での0埋めに関しては、桁数に制限が見られ無い点と、IPSocket.getaddress(8進数?)と返す値の異なってしまう点が気になります。 ## Linux(Mint12) / ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] require 'socket' p IPSocket.getaddress("011.0022.00033.000045") #=> "9.18.27.37" # 参考 ipaddr.rbを自分なりに読んでみた限り、次の要素に起因するのではないかとあたりをつけてみましたが・・・確信はありません。 * 全体的に、チェック用正規表現のメタ文字へ \A\z を使わず、 \A\Z や ^$ で括っていること * #initialize で、 IPSocket.getaddress が例外を返すかどうかに、正常異常の判断を大きく委ねていること * #in_addr で、1つのオクテットを \d+ のみでキャプチャしていること とりあえず、#in_addrのみを次のように上書きした際、Windowsと同様に動作することまでは確認できました。 require 'ipaddr' class IPAddr private remove_method :in_addr def in_addr(addr) if addr =~ /\A(?:(?:0|[1-9]\d{0,2})\.){3}(?:0|[1-9]\d{0,2})\z/ return addr.split('.').inject(0) { |i, s| n = s.to_i raise ArgumentError, 'invalid address' unless n <= 255 i << 8 | n } end return nil end end
on 2012-06-01 14:45
Issue #6479 has been updated by kachick (Kenichi Kamiya). 武者さん、なかむら(う)さん お二方とも、御返信下さり有難う御座います。 > cf. http://pubs.opengroup.org/onlinepubs/009696799/fun... 0埋め時のC側に於ける解釈は、8進数にする旨明記されていたのですね 由来が把握できて、すっきりしました。 > なお、あとは x:x:x:x:x:x:d.d.d.d 形式で今までは意図せずエラーとなっていた部分について仕様を詰めており、これが詰まり次第commitおよびbackportする予定です。もうしばらくお待ちください。 御丁寧に有難うございます。 手元の ipaddr.rb を利用しているコード内で問題が表面化している/いそうなわけでもないので、気長に待つつもりでした。 お手すきの際でも結構ですので、引き続き御検討頂けると嬉しいです。 ---------------------------------------- Bug #6479: ipaddr.rbの受け付ける書式が、プラットフォームによって異なる https://bugs.ruby-lang.org/issues/6479#change-26954 Author: kachick (Kenichi Kamiya) Status: Assigned Priority: Normal Assignee: knu (Akinori MUSHA) Category: lib Target version: 1.9.3 ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] # 状況 標準添付ライブラリの ipaddr.rb に於いて、アドレス書式チェック時の厳しさがプラットフォームによって異なるよう感じました。 IPv4で気がついた限りですが、次の2点でWindowsだと常に例外を吐き、Linuxだと書式によっては(自分にとって)想定し難い値を返します。 * 0埋めを含んだ場合 * 改行文字を含んだ場合 動作例を載せます。 ## 共通 require 'ipaddr' p IPAddr.new("11.22.33.45") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> ## Windows(7) / ruby 1.9.3p194 (2012-04-20) [i386-mingw32] # 以下全てで、同じ例外を吐きます。 p IPAddr.new("011.22.33.45") p IPAddr.new("011.0022.00033.000045") p IPAddr.new("011.0022.00033.000045\n") p IPAddr.new("011.0022.00033.000045\nfoo32/0024/bar \n/foobar ") p IPAddr.new("011.0022.00033.000045\n056.0067.00078.00089\nfoo32/0024/bar \n/foobar ") # 例外 ArgumentError: invalid address from C:/Ruby193/lib/ruby/1.9.1/ipaddr.rb:496:in `rescue in initialize' ## Linux(Mint12) / ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] # Windowsの際と同じ引数に対して、一つも例外を吐きません p IPAddr.new("011.22.33.45") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045\n") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045\nfoo32/0024/bar \n/foobar ") #=> #<IPAddr: IPv4:11.22.33.0/255.255.255.0> p IPAddr.new("011.0022.00033.000045\n056.0067.00078.00089\nfoo32/0024/bar \n/foobar ") #=> #<IPAddr: IPv4:45.67.78.0/255.255.255.0> # 希望 Windows環境下の例にみるよう、上記全てのパターンで例外を吐いてくれる方が自然に感じました。 特にLinux上での0埋めに関しては、桁数に制限が見られ無い点と、IPSocket.getaddress(8進数?)と返す値の異なってしまう点が気になります。 ## Linux(Mint12) / ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] require 'socket' p IPSocket.getaddress("011.0022.00033.000045") #=> "9.18.27.37" # 参考 ipaddr.rbを自分なりに読んでみた限り、次の要素に起因するのではないかとあたりをつけてみましたが・・・確信はありません。 * 全体的に、チェック用正規表現のメタ文字へ \A\z を使わず、 \A\Z や ^$ で括っていること * #initialize で、 IPSocket.getaddress が例外を返すかどうかに、正常異常の判断を大きく委ねていること * #in_addr で、1つのオクテットを \d+ のみでキャプチャしていること とりあえず、#in_addrのみを次のように上書きした際、Windowsと同様に動作することまでは確認できました。 require 'ipaddr' class IPAddr private remove_method :in_addr def in_addr(addr) if addr =~ /\A(?:(?:0|[1-9]\d{0,2})\.){3}(?:0|[1-9]\d{0,2})\z/ return addr.split('.').inject(0) { |i, s| n = s.to_i raise ArgumentError, 'invalid address' unless n <= 255 i << 8 | n } end return nil end end
on 2013-03-07 12:06
Issue #6479 has been updated by knu (Akinori MUSHA). Status changed from Assigned to Closed 本件を修正して様子を見るうちに2.0.0が正式リリースとなったので、すみませんが旧シリーズとなった1.9ではこのままとしたいと思います。 報告ありがとうございました。 ---------------------------------------- Bug #6479: ipaddr.rbの受け付ける書式が、プラットフォームによって異なる https://bugs.ruby-lang.org/issues/6479#change-37355 Author: kachick (Kenichi Kamiya) Status: Closed Priority: Normal Assignee: knu (Akinori MUSHA) Category: lib Target version: next minor ruby -v: ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] # 状況 標準添付ライブラリの ipaddr.rb に於いて、アドレス書式チェック時の厳しさがプラットフォームによって異なるよう感じました。 IPv4で気がついた限りですが、次の2点でWindowsだと常に例外を吐き、Linuxだと書式によっては(自分にとって)想定し難い値を返します。 * 0埋めを含んだ場合 * 改行文字を含んだ場合 動作例を載せます。 ## 共通 require 'ipaddr' p IPAddr.new("11.22.33.45") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> ## Windows(7) / ruby 1.9.3p194 (2012-04-20) [i386-mingw32] # 以下全てで、同じ例外を吐きます。 p IPAddr.new("011.22.33.45") p IPAddr.new("011.0022.00033.000045") p IPAddr.new("011.0022.00033.000045\n") p IPAddr.new("011.0022.00033.000045\nfoo32/0024/bar \n/foobar ") p IPAddr.new("011.0022.00033.000045\n056.0067.00078.00089\nfoo32/0024/bar \n/foobar ") # 例外 ArgumentError: invalid address from C:/Ruby193/lib/ruby/1.9.1/ipaddr.rb:496:in `rescue in initialize' ## Linux(Mint12) / ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] # Windowsの際と同じ引数に対して、一つも例外を吐きません p IPAddr.new("011.22.33.45") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045\n") #=> #<IPAddr: IPv4:11.22.33.45/255.255.255.255> p IPAddr.new("011.0022.00033.000045\nfoo32/0024/bar \n/foobar ") #=> #<IPAddr: IPv4:11.22.33.0/255.255.255.0> p IPAddr.new("011.0022.00033.000045\n056.0067.00078.00089\nfoo32/0024/bar \n/foobar ") #=> #<IPAddr: IPv4:45.67.78.0/255.255.255.0> # 希望 Windows環境下の例にみるよう、上記全てのパターンで例外を吐いてくれる方が自然に感じました。 特にLinux上での0埋めに関しては、桁数に制限が見られ無い点と、IPSocket.getaddress(8進数?)と返す値の異なってしまう点が気になります。 ## Linux(Mint12) / ruby 1.9.3p194 (2012-04-20 revision 35410) [i686-linux] require 'socket' p IPSocket.getaddress("011.0022.00033.000045") #=> "9.18.27.37" # 参考 ipaddr.rbを自分なりに読んでみた限り、次の要素に起因するのではないかとあたりをつけてみましたが・・・確信はありません。 * 全体的に、チェック用正規表現のメタ文字へ \A\z を使わず、 \A\Z や ^$ で括っていること * #initialize で、 IPSocket.getaddress が例外を返すかどうかに、正常異常の判断を大きく委ねていること * #in_addr で、1つのオクテットを \d+ のみでキャプチャしていること とりあえず、#in_addrのみを次のように上書きした際、Windowsと同様に動作することまでは確認できました。 require 'ipaddr' class IPAddr private remove_method :in_addr def in_addr(addr) if addr =~ /\A(?:(?:0|[1-9]\d{0,2})\.){3}(?:0|[1-9]\d{0,2})\z/ return addr.split('.').inject(0) { |i, s| n = s.to_i raise ArgumentError, 'invalid address' unless n <= 255 i << 8 | n } end return nil end end
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.