Bug #2374

URI.regexp('http') が 'http://' にマッチする

Added by Kouhei Yanagita almost 6 years ago. Updated over 4 years ago.

Status:Rejected
Priority:Normal
Assignee:akira yamada
ruby -v:ruby 1.9.2dev (2009-11-16 trunk 25792) [i686-linux] Backport:

Description

=begin
URI.regexp('http') が 'http://' にマッチしますが、'http://' は有効な URI ではありません。

% ~/local/ruby-trunk/bin/ruby -v -ruri -e 'URI.regexp =~ "http://"; p $&'
ruby 1.9.2dev (2009-11-16 trunk 25792) [i686-linux]
"http://"

http://www.ietf.org/rfc/rfc3986 [Page 20]

If the URI scheme defines a default for host, then that default
applies when the host subcomponent is undefined or when the
registered name is empty (zero length).  For example, the "file" URI
scheme is defined so that no authority, an empty host, and
"localhost" all mean the end-user's machine, whereas the "http"
scheme considers a missing authority or empty host invalid.

=end

History

#1 Updated by Yui NARUSE almost 6 years ago

  • Status changed from Open to Assigned
  • Assignee set to akira yamada

=begin

=end

#2 Updated by Yui NARUSE over 5 years ago

=begin
URI を正規表現でパースするという発想自体にそもそも若干の無理があるように思うので、
URI.regexp は obsolete にしませんか
=end

#3 Updated by Yui NARUSE over 5 years ago

=begin
(2009/12/31 23:54), Tanaka Akira wrote:

2009年12月31日23:47 Yui NARUSE redmine@ruby-lang.org:

URI を正規表現でパースするという発想自体にそもそも若干の無理があるように思うので、
URI.regexp は obsolete にしませんか

無理というのは具体的にはどういう話でしょう?

まず、必ずしも正規表現でのパースが可能な事が保証されていない事です。
実際問題としてはたいていパース可能なのですが、
たとえば urn:isbn あたりはちょっと可能とは言わないでしょう。
http://www.din.or.jp/~ohzaki/regex.htm#ISBN

次に、スキームによって正規表現の中身を切り替える必要がある点です。
現状でもスキームを与える事はできますが、その結果はほとんど変わりません。
理屈の上ではそれぞれ切り替えるように変えればいいとも言えますが、
長期間現状で放置されてきたという現実があります。
現状は、個別のスキーマについて言えば誤った正規表現を提供しているわけで、
有害であるように感じます。

さらに、正規表現を返すという API は規格の更新に弱いです。
URI 全体に言える事ですが、内部実装を露出しすぎていて、
規格の更新に対応しづらくなっています。
URI.regexp の場合、取得した正規表現をマッチに使って $1 とかを取っている
うちは問題ありませんが、Regexp#source を呼び始めた瞬間互換性の確保が
極めて困難になります。

結局の所、現状に問題があるが、問題がない状態を維持するのは大変であり、
変えると互換性に問題が出る恐れがあるということになります。

で、わたしのこれへの対応案として、以下を提案するという事です。
* URI.regexp は現状を仕様としていじらない
* 長期的には obsolete として、きりのいいところで廃止
=end

#4 Updated by Yui NARUSE over 5 years ago

=begin
(2010/01/01 12:29), Tanaka Akira wrote:

2010年1月1日1:33 Yui NARUSE redmine@ruby-lang.org:

まず、必ずしも正規表現でのパースが可能な事が保証されていない事です。
実際問題としてはたいていパース可能なのですが、
たとえば urn:isbn あたりはちょっと可能とは言わないでしょう。
http://www.din.or.jp/~ohzaki/regex.htm#ISBN

べつに完全でなくても役に立てばいいんじゃないですかねぇ。
テキストの中から URI を探したいっていうのはいかにもありそうな話ですし。

ふむ、それでは、これは役に立つのかなぁ、と思っていたのですが、後述。

なお、ISBN については鬼車で \g を使えばずいぶんと短くできると思います。
というか、ISBN は \g を要望したときに使った例でもあります。

なるほど。

次に、スキームによって正規表現の中身を切り替える必要がある点です。
現状でもスキームを与える事はできますが、その結果はほとんど変わりません。
理屈の上ではそれぞれ切り替えるように変えればいいとも言えますが、
長期間現状で放置されてきたという現実があります。
現状は、個別のスキーマについて言えば誤った正規表現を提供しているわけで、
有害であるように感じます。

正規表現では記述できない可能性を考えるならむしろそれは必然的な仕様なのでは?
URI.regexp はおおざっぱに取り出して、正しいかどうかはさらに URI.parse で確認
する必要があるのでしょう。

なるほど。
その目的ならば、URI.scan(text, schemes) 等の API にした上で、
RFC 3986 Appendix C. Delimiting a URI in Context にあるような折り返しの
考慮も必要な気もしないでもないですが。

さらに、正規表現を返すという API は規格の更新に弱いです。
URI 全体に言える事ですが、内部実装を露出しすぎていて、
規格の更新に対応しづらくなっています。
URI.regexp の場合、取得した正規表現をマッチに使って $1 とかを取っている
うちは問題ありませんが、Regexp#source を呼び始めた瞬間互換性の確保が
極めて困難になります。

URI.regexp は規格で使っている非終端記号の名前を使っていないぶん、
むしろ規格の更新には強い気がします。

改めて URI.regexp の rdoc を読むと、$1 等の使用は非サポートなんですね。
ならば、規格の更新には強いですね。

--
NARUSE, Yui naruse@airemix.jp

=end

#5 Updated by Yusuke Endoh over 5 years ago

  • Status changed from Assigned to Rejected
  • Target version set to 2.0.0

=begin
遠藤です。

URI.regexp の rdoc には

Returns a Regexp object which matches to URI-like strings.

と書いてあります。"URI-like" であり、valid な URI のみにマッチ
することが意図されたものではないと考えます。

なので、気持ちはわかるので申し訳ないですが、このチケットは一旦
reject としたいと思います。すみません。

それでも invalid な URI にはマッチしないでほしいと思うなら、
Feature チケットを書いてください。

--
Yusuke Endoh mame@tsg.ne.jp
=end

Also available in: Atom PDF