埋め込まれた soundcloud-track URL を iframe に変更するメソッドをテストする場合。結果をエスケープするときにバグが発生しました。
CASE 2 で +token+ をエスケープすると壊れる理由を誰か説明できますか? 結果をそのまま使用して追加しても問題ありません。
2 つのケースを以下に詳しく示します。
#ruby --version
# => ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin12.2.1]
ケース1
require 'cgi'
class String
def embedda
compiled = self
compiled = soundcloud_replace(compiled)
return compiled
end
private
def soundcloud_replace(compiled)
r = /(https?:\/\/(?:www.)?soundcloud.com\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*(?!\/sets(?:\/|$))(?:\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*){1,2}\/?)/i
compiled.gsub!(r) { |match| soundcloud_player(match) }
return compiled
end
def soundcloud_player(token)
# return token # => +matched soundcloud url+ in pry
# puts token # => +matched soundcloud url+ in pry
url_encoded_string = CGI::escape(token)
# puts url_encoded_string # => +escaped matched soundcloud url+
# "<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=#{token}\"></iframe>"
# => Correct interpolated string with non-encoded url
"<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=#{url_encoded_string}\"></iframe>"
# => Correct interpolated string with encoded url
end
end
ケース 2
require 'cgi'
class String
def embedda
compiled = self
compiled = soundcloud_replace(compiled)
return compiled
end
private
def soundcloud_replace(compiled)
compiled.gsub!(/(https?:\/\/(?:www.)?soundcloud.com\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*(?!\/sets(?:\/|$))(?:\/[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*){1,2}\/?)/i, soundcloud_player("\\1"))
return compiled
end
def soundcloud_player(token)
# return token # => +matched soundcloud url+ in pry
# puts token # => /1 in pry
url_encoded_string = CGI::escape(token)
# puts url_encoded_string = CGI::escape(token) # => %5C1 in pry
# "<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=#{token}\"></iframe>"
# => Correct interpolated string with non-encoded url
"<iframe width=\"100%\" height=\"166\" scrolling=\"no\" frameborder=\"no\" src=\"https://w.soundcloud.com/player/?url=#{url_encoded_string}\"></iframe>"
# => Interpolated string with ...?url=%5C1
end
end