* [ruby-dev:50625] [Ruby trunk Bug#15057] REXML::Text#value returns a double unescaped string in non-raw mode
[not found] <redmine.issue-15057.20180902092250@ruby-lang.org>
@ 2018-09-02 9:22 ` rnanba
2018-09-02 13:20 ` [ruby-dev:50629] [Ruby trunk Bug#15057][Feedback] " kou
` (6 subsequent siblings)
7 siblings, 0 replies; 8+ messages in thread
From: rnanba @ 2018-09-02 9:22 UTC (permalink / raw)
To: ruby-dev
Issue #15057 has been reported by rna (Ryosuke Nanba).
----------------------------------------
Bug #15057: REXML::Text#value returns a double unescaped string in non-raw mode
https://bugs.ruby-lang.org/issues/15057
* Author: rna (Ryosuke Nanba)
* Status: Open
* Priority: Normal
* Assignee:
* Target version:
* ruby -v: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
`REXML::Text` オブジェクトが非rawモードの場合、`REXML::Text#value` がエスケープ済みのテキストを二重にエスケープ解除された文字列を返します。
例:
~~~
require 'rexml/document'
t = REXML::Text.new("< <", false, nil, false)
t.to_s # => "&lt; <"
t.value # => "< <" (expected: "< <")
~~~
`REXML::Text#value` のコメントに以下のような記述があるため、上の挙動は期待通りのように見えますが、このコメントそのものが誤りだと思います。
~~~
# t = Text.new( "< & &s; russell", false, nil, false )
# t.value #-> "< & sean russell"
~~~
非rawモードではコンストラクタの第一引数に渡された文字列はテキストノードが表す文字列そのものを意味するはずです。上で渡された文字列中の "&s;" は実体参照ではなく単なる3文字のテキストを意味します。`t.value` は "< & &s; russell" であるべきだと思います。
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 8+ messages in thread
* [ruby-dev:50629] [Ruby trunk Bug#15057][Feedback] REXML::Text#value returns a double unescaped string in non-raw mode
[not found] <redmine.issue-15057.20180902092250@ruby-lang.org>
2018-09-02 9:22 ` [ruby-dev:50625] [Ruby trunk Bug#15057] REXML::Text#value returns a double unescaped string in non-raw mode rnanba
@ 2018-09-02 13:20 ` kou
2018-09-02 17:29 ` [ruby-dev:50631] [Ruby trunk Bug#15057] " rnanba
` (5 subsequent siblings)
7 siblings, 0 replies; 8+ messages in thread
From: kou @ 2018-09-02 13:20 UTC (permalink / raw)
To: ruby-dev
Issue #15057 has been updated by kou (Kouhei Sutou).
Status changed from Open to Feedback
Assignee set to kou (Kouhei Sutou)
DOMでも`nodeValue`の値は実体参照を解決した値になるので今の挙動で問題ないように思うんですが、どんなユースケースで使おうとして今の挙動は間違っていると考えたか教えてもらえますか?
> 非rawモードではコンストラクタの第一引数に渡された文字列はテキストノードが表す文字列そのものを意味するはずです。
こうするべきだと考えた理由というか。
----------------------------------------
Bug #15057: REXML::Text#value returns a double unescaped string in non-raw mode
https://bugs.ruby-lang.org/issues/15057#change-73849
* Author: rna (Ryosuke Nanba)
* Status: Feedback
* Priority: Normal
* Assignee: kou (Kouhei Sutou)
* Target version:
* ruby -v: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
`REXML::Text` オブジェクトが非rawモードの場合、`REXML::Text#value` がエスケープ済みのテキストを二重にエスケープ解除された文字列を返します。
例:
~~~
require 'rexml/document'
t = REXML::Text.new("< <", false, nil, false)
t.to_s # => "&lt; <"
t.value # => "< <" (expected: "< <")
~~~
`REXML::Text#value` のコメントに以下のような記述があるため、上の挙動は期待通りのように見えますが、このコメントそのものが誤りだと思います。
~~~
# t = Text.new( "< & &s; russell", false, nil, false )
# t.value #-> "< & sean russell"
~~~
非rawモードではコンストラクタの第一引数に渡された文字列はテキストノードが表す文字列そのものを意味するはずです。上で渡された文字列中の "&s;" は実体参照ではなく単なる3文字のテキストを意味します。`t.value` は "< & &s; russell" であるべきだと思います。
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 8+ messages in thread
* [ruby-dev:50631] [Ruby trunk Bug#15057] REXML::Text#value returns a double unescaped string in non-raw mode
[not found] <redmine.issue-15057.20180902092250@ruby-lang.org>
2018-09-02 9:22 ` [ruby-dev:50625] [Ruby trunk Bug#15057] REXML::Text#value returns a double unescaped string in non-raw mode rnanba
2018-09-02 13:20 ` [ruby-dev:50629] [Ruby trunk Bug#15057][Feedback] " kou
@ 2018-09-02 17:29 ` rnanba
2018-09-03 0:22 ` [ruby-dev:50632] " kou
` (4 subsequent siblings)
7 siblings, 0 replies; 8+ messages in thread
From: rnanba @ 2018-09-02 17:29 UTC (permalink / raw)
To: ruby-dev
Issue #15057 has been updated by rna (Ryosuke Nanba).
> DOMでもnodeValueの値は実体参照を解決した値になるので今の挙動で問題ないように思うんですが、
JavaScript の DOM でも `Text` のコンストラクタ引数で渡した文字列はパースの対象にならずにそのままテキストノードが表す文字列になります。
~~~
<p id="p"></p>
<script>
t = new Text("< <");
console.log(t.nodeValue); // コンソールに「< <」が出力
p.appendChild(t); // 画面に「< <」と表示。
</script>
~~~
実体参照が解決されるのは XML 文書実体(ソースコード)からパースする段階の話で、DOM API としては通常パース済みの文字列しか扱いません。
DOM はともかくとして、REXMLの仕様として(非rawモードで) `Text` のコンストラクタ引数はパースされることになっているのだ、ということであれば、以下の挙動はバグということになってしまいます。
~~~
t = REXML::Text.new("< <", false, nil, false)
t.to_s # => "&lt; <" (expected?: "< <" (or Error?))
~~~
> どんなユースケースで使おうとして今の挙動は間違っていると考えたか教えてもらえますか?
atomutil 0.1.4 でテキストノードを要素から要素にコピーするユースケースでエスケープが解除されてしまってコピーにならないという現象が発生していました。
https://github.com/lyokato/ruby-atomutil/blob/954c5d1b387bff63db3462d19d3f7abf196d2b1f/lib/atomutil.rb#L526 (`element` と `value.elem` が `REXML::Element` です):
~~~
element.text = value.elem.text unless value.elem.text.nil?
~~~
----------------------------------------
Bug #15057: REXML::Text#value returns a double unescaped string in non-raw mode
https://bugs.ruby-lang.org/issues/15057#change-73853
* Author: rna (Ryosuke Nanba)
* Status: Feedback
* Priority: Normal
* Assignee: kou (Kouhei Sutou)
* Target version:
* ruby -v: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
`REXML::Text` オブジェクトが非rawモードの場合、`REXML::Text#value` がエスケープ済みのテキストを二重にエスケープ解除された文字列を返します。
例:
~~~
require 'rexml/document'
t = REXML::Text.new("< <", false, nil, false)
t.to_s # => "&lt; <"
t.value # => "< <" (expected: "< <")
~~~
`REXML::Text#value` のコメントに以下のような記述があるため、上の挙動は期待通りのように見えますが、このコメントそのものが誤りだと思います。
~~~
# t = Text.new( "< & &s; russell", false, nil, false )
# t.value #-> "< & sean russell"
~~~
非rawモードではコンストラクタの第一引数に渡された文字列はテキストノードが表す文字列そのものを意味するはずです。上で渡された文字列中の "&s;" は実体参照ではなく単なる3文字のテキストを意味します。`t.value` は "< & &s; russell" であるべきだと思います。
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 8+ messages in thread
* [ruby-dev:50632] [Ruby trunk Bug#15057] REXML::Text#value returns a double unescaped string in non-raw mode
[not found] <redmine.issue-15057.20180902092250@ruby-lang.org>
` (2 preceding siblings ...)
2018-09-02 17:29 ` [ruby-dev:50631] [Ruby trunk Bug#15057] " rnanba
@ 2018-09-03 0:22 ` kou
2018-09-03 5:40 ` [ruby-dev:50633] " rnanba
` (3 subsequent siblings)
7 siblings, 0 replies; 8+ messages in thread
From: kou @ 2018-09-03 0:22 UTC (permalink / raw)
To: ruby-dev
Issue #15057 has been updated by kou (Kouhei Sutou).
なるほど。
atomutilでそうなるケースを試してみたいので再現するAtomとサンプルコードを提供してもらえませんか?
----------------------------------------
Bug #15057: REXML::Text#value returns a double unescaped string in non-raw mode
https://bugs.ruby-lang.org/issues/15057#change-73855
* Author: rna (Ryosuke Nanba)
* Status: Feedback
* Priority: Normal
* Assignee: kou (Kouhei Sutou)
* Target version:
* ruby -v: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
`REXML::Text` オブジェクトが非rawモードの場合、`REXML::Text#value` がエスケープ済みのテキストを二重にエスケープ解除された文字列を返します。
例:
~~~
require 'rexml/document'
t = REXML::Text.new("< <", false, nil, false)
t.to_s # => "&lt; <"
t.value # => "< <" (expected: "< <")
~~~
`REXML::Text#value` のコメントに以下のような記述があるため、上の挙動は期待通りのように見えますが、このコメントそのものが誤りだと思います。
~~~
# t = Text.new( "< & &s; russell", false, nil, false )
# t.value #-> "< & sean russell"
~~~
非rawモードではコンストラクタの第一引数に渡された文字列はテキストノードが表す文字列そのものを意味するはずです。上で渡された文字列中の "&s;" は実体参照ではなく単なる3文字のテキストを意味します。`t.value` は "< & &s; russell" であるべきだと思います。
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 8+ messages in thread
* [ruby-dev:50633] [Ruby trunk Bug#15057] REXML::Text#value returns a double unescaped string in non-raw mode
[not found] <redmine.issue-15057.20180902092250@ruby-lang.org>
` (3 preceding siblings ...)
2018-09-03 0:22 ` [ruby-dev:50632] " kou
@ 2018-09-03 5:40 ` rnanba
2018-09-04 5:12 ` [ruby-dev:50634] " kou
` (2 subsequent siblings)
7 siblings, 0 replies; 8+ messages in thread
From: rnanba @ 2018-09-03 5:40 UTC (permalink / raw)
To: ruby-dev
Issue #15057 has been updated by rna (Ryosuke Nanba).
> atomutilでそうなるケースを試してみたいので再現するAtomとサンプルコードを提供してもらえませんか?
これでどうでしょう?
~~~
require 'atomutil'
entry = Atom::Entry.new
entry.content = "<br>"
puts entry.to_s
~~~
entry.to_s は実際に投稿する場合 HTTP の request body になります(参照: Atom::Client#create_resource)。
上のサンプルは「HTMLタグを記述可能なテキスト形式での投稿を受理するブログサービス(はてなブログのはてな記法モード等)で、HTMLタグ <br> の説明を書くためタグをエスケープして記述した」という想定です。ブログサービス側では atom の content 要素の内容をパースしたものをテキスト形式の投稿データとして扱います。
期待する結果はブログエントリに br タグのソースコードが表示されることですが、実際には改行が表示されます(本物の br タグとして機能してしまう)。
ちなみに本件は元々 HatenaBlogWriter v0.5 https://github.com/rnanba/HatenaBlogWriter/tree/v0.5 に対する不具合報告が発端です(master には現在 monkey patch による回避コードが入っています)。はてなブログで実際に試す場合はこちらを参考にしてください。
----------------------------------------
Bug #15057: REXML::Text#value returns a double unescaped string in non-raw mode
https://bugs.ruby-lang.org/issues/15057#change-73859
* Author: rna (Ryosuke Nanba)
* Status: Feedback
* Priority: Normal
* Assignee: kou (Kouhei Sutou)
* Target version:
* ruby -v: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
`REXML::Text` オブジェクトが非rawモードの場合、`REXML::Text#value` がエスケープ済みのテキストを二重にエスケープ解除された文字列を返します。
例:
~~~
require 'rexml/document'
t = REXML::Text.new("< <", false, nil, false)
t.to_s # => "&lt; <"
t.value # => "< <" (expected: "< <")
~~~
`REXML::Text#value` のコメントに以下のような記述があるため、上の挙動は期待通りのように見えますが、このコメントそのものが誤りだと思います。
~~~
# t = Text.new( "< & &s; russell", false, nil, false )
# t.value #-> "< & sean russell"
~~~
非rawモードではコンストラクタの第一引数に渡された文字列はテキストノードが表す文字列そのものを意味するはずです。上で渡された文字列中の "&s;" は実体参照ではなく単なる3文字のテキストを意味します。`t.value` は "< & &s; russell" であるべきだと思います。
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 8+ messages in thread
* [ruby-dev:50634] [Ruby trunk Bug#15057] REXML::Text#value returns a double unescaped string in non-raw mode
[not found] <redmine.issue-15057.20180902092250@ruby-lang.org>
` (4 preceding siblings ...)
2018-09-03 5:40 ` [ruby-dev:50633] " rnanba
@ 2018-09-04 5:12 ` kou
2018-09-04 7:08 ` [ruby-dev:50635] " rnanba
2018-09-04 14:24 ` [ruby-dev:50636] [Ruby trunk Bug#15057][Rejected] " kou
7 siblings, 0 replies; 8+ messages in thread
From: kou @ 2018-09-04 5:12 UTC (permalink / raw)
To: ruby-dev
Issue #15057 has been updated by kou (Kouhei Sutou).
ありがとうございます。確認できました。
現状の動きが変だという気持ちはわかるのですが、`Text#value`のドキュメントに
> This ignores the 'raw' attribute setting
と書いているので、`raw`のときもそうじゃないときも期待した挙動にするのは、互換性を維持したままではムリなんですよねぇ。
なので、`element1.text = element2.text`という使い方がよくないんですよねぇ。ただ、こう書けたほうがうれしいので、これに匹敵する使い勝手のAPIを考えておきます。
互換性は壊したくないので、現状ではatomutilでは次のように使ってもらいたいです。
```diff
diff --git a/lib/atomutil.rb b/lib/atomutil.rb
index 9bb9e0c..6d9b985 100644
--- a/lib/atomutil.rb
+++ b/lib/atomutil.rb
@@ -523,7 +523,10 @@ module Atom
element.add_attribute a
end
end
- element.text = value.elem.text unless value.elem.text.nil?
+ text = value.elem.get_text
+ unless text.nil?
+ element.text = REXML::Text.new(text.to_s, true, nil, true)
+ end
else
if value.is_a?(REXML::Element)
element.add_element value.deep_clone
```
----------------------------------------
Bug #15057: REXML::Text#value returns a double unescaped string in non-raw mode
https://bugs.ruby-lang.org/issues/15057#change-73871
* Author: rna (Ryosuke Nanba)
* Status: Feedback
* Priority: Normal
* Assignee: kou (Kouhei Sutou)
* Target version:
* ruby -v: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
`REXML::Text` オブジェクトが非rawモードの場合、`REXML::Text#value` がエスケープ済みのテキストを二重にエスケープ解除された文字列を返します。
例:
~~~
require 'rexml/document'
t = REXML::Text.new("< <", false, nil, false)
t.to_s # => "&lt; <"
t.value # => "< <" (expected: "< <")
~~~
`REXML::Text#value` のコメントに以下のような記述があるため、上の挙動は期待通りのように見えますが、このコメントそのものが誤りだと思います。
~~~
# t = Text.new( "< & &s; russell", false, nil, false )
# t.value #-> "< & sean russell"
~~~
非rawモードではコンストラクタの第一引数に渡された文字列はテキストノードが表す文字列そのものを意味するはずです。上で渡された文字列中の "&s;" は実体参照ではなく単なる3文字のテキストを意味します。`t.value` は "< & &s; russell" であるべきだと思います。
--
https://bugs.ruby-lang.org/
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [ruby-dev:50635] [Ruby trunk Bug#15057] REXML::Text#value returns a double unescaped string in non-raw mode
[not found] <redmine.issue-15057.20180902092250@ruby-lang.org>
` (5 preceding siblings ...)
2018-09-04 5:12 ` [ruby-dev:50634] " kou
@ 2018-09-04 7:08 ` rnanba
2018-09-04 14:24 ` [ruby-dev:50636] [Ruby trunk Bug#15057][Rejected] " kou
7 siblings, 0 replies; 8+ messages in thread
From: rnanba @ 2018-09-04 7:08 UTC (permalink / raw)
To: ruby-dev
Issue #15057 has been updated by rna (Ryosuke Nanba).
>> This ignores the 'raw' attribute setting
>
> と書いているので、rawのときもそうじゃないときも期待した挙動にするのは、互換性を維持したままではムリなんですよねぇ。
>
> なので、element1.text = element2.textという使い方がよくないんですよねぇ。ただ、こう書けたほうがうれしいので、これに匹敵する使い勝手のAPIを考えておきます。
なるほど。`REXML::Element#text` も同様のコメントがあってセマンティクスを変えられないと。残念ですが仕方がないですかね… メジャーバージョンアップの際は再検討していただけると幸いです。
> 互換性は壊したくないので、現状ではatomutilでは次のように使ってもらいたいです。
了解しました。atomutil の方にはこちらから報告しておきます。
----------------------------------------
Bug #15057: REXML::Text#value returns a double unescaped string in non-raw mode
https://bugs.ruby-lang.org/issues/15057#change-73872
* Author: rna (Ryosuke Nanba)
* Status: Feedback
* Priority: Normal
* Assignee: kou (Kouhei Sutou)
* Target version:
* ruby -v: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
`REXML::Text` オブジェクトが非rawモードの場合、`REXML::Text#value` がエスケープ済みのテキストを二重にエスケープ解除された文字列を返します。
例:
~~~
require 'rexml/document'
t = REXML::Text.new("< <", false, nil, false)
t.to_s # => "&lt; <"
t.value # => "< <" (expected: "< <")
~~~
`REXML::Text#value` のコメントに以下のような記述があるため、上の挙動は期待通りのように見えますが、このコメントそのものが誤りだと思います。
~~~
# t = Text.new( "< & &s; russell", false, nil, false )
# t.value #-> "< & sean russell"
~~~
非rawモードではコンストラクタの第一引数に渡された文字列はテキストノードが表す文字列そのものを意味するはずです。上で渡された文字列中の "&s;" は実体参照ではなく単なる3文字のテキストを意味します。`t.value` は "< & &s; russell" であるべきだと思います。
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 8+ messages in thread
* [ruby-dev:50636] [Ruby trunk Bug#15057][Rejected] REXML::Text#value returns a double unescaped string in non-raw mode
[not found] <redmine.issue-15057.20180902092250@ruby-lang.org>
` (6 preceding siblings ...)
2018-09-04 7:08 ` [ruby-dev:50635] " rnanba
@ 2018-09-04 14:24 ` kou
7 siblings, 0 replies; 8+ messages in thread
From: kou @ 2018-09-04 14:24 UTC (permalink / raw)
To: ruby-dev
Issue #15057 has been updated by kou (Kouhei Sutou).
Status changed from Feedback to Rejected
> 了解しました。atomutil の方にはこちらから報告しておきます。
ありがとうございます。では、このチケットはクローズしておきます。
----------------------------------------
Bug #15057: REXML::Text#value returns a double unescaped string in non-raw mode
https://bugs.ruby-lang.org/issues/15057#change-73878
* Author: rna (Ryosuke Nanba)
* Status: Rejected
* Priority: Normal
* Assignee: kou (Kouhei Sutou)
* Target version:
* ruby -v: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
* Backport: 2.3: UNKNOWN, 2.4: UNKNOWN, 2.5: UNKNOWN
----------------------------------------
`REXML::Text` オブジェクトが非rawモードの場合、`REXML::Text#value` がエスケープ済みのテキストを二重にエスケープ解除された文字列を返します。
例:
~~~
require 'rexml/document'
t = REXML::Text.new("< <", false, nil, false)
t.to_s # => "&lt; <"
t.value # => "< <" (expected: "< <")
~~~
`REXML::Text#value` のコメントに以下のような記述があるため、上の挙動は期待通りのように見えますが、このコメントそのものが誤りだと思います。
~~~
# t = Text.new( "< & &s; russell", false, nil, false )
# t.value #-> "< & sean russell"
~~~
非rawモードではコンストラクタの第一引数に渡された文字列はテキストノードが表す文字列そのものを意味するはずです。上で渡された文字列中の "&s;" は実体参照ではなく単なる3文字のテキストを意味します。`t.value` は "< & &s; russell" であるべきだと思います。
--
https://bugs.ruby-lang.org/
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-09-04 14:24 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <redmine.issue-15057.20180902092250@ruby-lang.org>
2018-09-02 9:22 ` [ruby-dev:50625] [Ruby trunk Bug#15057] REXML::Text#value returns a double unescaped string in non-raw mode rnanba
2018-09-02 13:20 ` [ruby-dev:50629] [Ruby trunk Bug#15057][Feedback] " kou
2018-09-02 17:29 ` [ruby-dev:50631] [Ruby trunk Bug#15057] " rnanba
2018-09-03 0:22 ` [ruby-dev:50632] " kou
2018-09-03 5:40 ` [ruby-dev:50633] " rnanba
2018-09-04 5:12 ` [ruby-dev:50634] " kou
2018-09-04 7:08 ` [ruby-dev:50635] " rnanba
2018-09-04 14:24 ` [ruby-dev:50636] [Ruby trunk Bug#15057][Rejected] " kou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).