QA@IT

この2つの文字列の違いは?

1860 PV

現在、自分のサーバにあるRSSをパースしようとしています。しかしファイルの読み込み時にファイルが読み込まれずにエラーになってしまいます。しかしfilepathをハードコーティングすればファイルが読み込まれます。

具体的に例を挙げて説明します。現状と際が出ないように余分な部分も少し書いてますが、主にs_hardとs_softをみてください。

$root_directory_path = File.expand_path(__FILE__)[0..File.expand_path(__FILE__).rindex("/")] + "../"

rss_file_name = "topselling_free_rss.xml"

#s_hardの内容は$root_directory_path + "public/" + rss_file_name の出力結果
s_hard = "/Users/lain/Dropbox/RailsProject/androidrss/crontab/../public/topselling_free_rss.xml"
s_soft = $root_directory_path + "public/" + rss_file_name
if s_hard == s_soft#ここはtrueを返します。
    p RSS::Parser.parse(s_soft)# nil
end
p RSS::Parser.parse(s_hard)# <?xml version="1.0" encoding="UTF-8"?>
                                             #<rss version="2.0" ....

なおこのrbファイルはルートディレクトリから実行しました。

RSS::Parser.parse(s_soft)の出力結果はnilで
RSS::Parser.parse(s_hard)の出力結果は正常です。

私の目には、s_softとs_hardは同じstringに見えます。
この2つの変数の違いはなんですか?ご回答いただけると幸いです。

回答

s_soft は汚染されています。(参考:Rubyのセキュリティモデル http://doc.ruby-lang.org/ja/1.9.3/doc/spec=2fsafelevel.html

s_soft.tainted? # => true
s_hard.tainted? # => false

汚染が RSS::Parser.parse に影響するかは分かりませんが、関係している可能性はあります。どこかでセキュリティレベル $SAFE の値が設定されているかどうか、 また s_soft の汚染を取り除いたら動作するかどうか確認してみてください。

RSS::Parser.parse(s_soft.untaint)
編集 履歴 (0)
  • 汚染を取り除くと動作しました。汚染に関して勉強になりました、ありがとうございます。 -

Rubyは初心者ですがFile.expand_path(__FILE__) をすると RSS::Parser.parse` がnil` を返しますね。
でも、以下だとなんで通るんだろう。同じ様にpathを読んでいるように見えるんだけどなぁ。

path_to_xml=File.join(File.dirname(__FILE__),"..","public",rss_file_name)
p RSS::Parser.parse(path_to_xml) # => not nil

もっと精進しよう。

編集 履歴 (0)
  • 試していただいてありがとうございます。
    File.expand_path(__FILE__)でとった値はすべて汚染されるようです。
    -
ウォッチ

この質問への回答やコメントをメールでお知らせします。