英文:
Why does Rails sanitize() perform differently in rspec than in a model?
问题
在我的config/initializers
中,我在String
类中添加了以下内容:
class String
def sanitize(options={ tags: %w(div p span strong b em i br ol ul li) })
ActionController::Base.helpers.sanitize(self, options)
end
end
在我的本地开发站点上,这会将所有不允许的标签转换为编码的 HTML,所以
"<span><img src=\"nonexistent.png\" onerror=\"alert('This alert should not be shown');\"></span><p>Build something</p>"
会变成
"<span>&lt;img src=\"nonexistent.png\" onerror=\"alert('This alert should not be shown');\"/&gt;</span><p>Build something</p> "
但是在RSpec中,在同一个字符串上调用相同的方法会导致:
"<span></span><p>Build something</p>"
它不再编码图像标签;它只是完全删除标签。在模型规范中发生这种不同行为的原因是什么?
英文:
In my config/initializers
I added the following to the String
class:
class String
def sanitize(options={ tags: %w(div p span strong b em i br ol ul li) })
ActionController::Base.helpers.sanitize(self, options)
end
end
On my local development site, this converts all disallowed tags to encoded html, so
"<span><img src=\"nonexistent.png\" onerror=\"alert('This alert should not be shown');\"></span><p>Build something</p>"
becomes
"<span>&lt;img src=\"nonexistent.png\" onerror=\"alert('This alert should not be shown');\"/&gt;</span><p>Build something</p> "
But in rspec, calling the same method on the same string results in:
"<span></span><p>Build something</p>"
It is not encoding the image tag anymore; it is just stripping the tag out altogether. What is the cause of this different behavior in a model spec than in a model?
答案1
得分: 2
以下是翻译好的内容:
难以确定。容易找出。大多数情况下:不要这样做。
难以确定:
是其他东西在干扰您的清理方法,还是您在干扰别人的?
容易找出:
编写一个测试。在调用清理方法之前设置断点。逐步执行并继续执行。您很可能很快就会看到发生了什么。
不要这样做:
- 其他东西要么添加了该方法,要么您可以从其他地方调用清理方法。我不确定对您来说什么是正确的解决方案,但是可能一个控制器或助手方法
sanitize(string, options)
比您所做的更好。毕竟,这就是您在调用的内容。 - 如果必须添加一个方法,请不要打开类并像您所做的那样破坏它:
module StringSanitizer
def sanitize(...)
super # 如果适用-查看它是否已经存在于类中,或者是否已经有其他东西添加了它
ActionController::Base.helpers.sanitize(self, options)
end
end
String.prepend(StringSanitizer)
英文:
Hard to know. Easy to find out. Mostly: don't do that.
Hard to know:
Something else is clobbering your sanitize method or you're clobbering someone else's?
Easy to find out:
Write a test. Set a breakpoint before calling sanitize. Step into it and keep stepping. You'll probably see what's going on pretty quickly.
Don't do that:
- Other things either add that method or you can call sanitize from something else. I'm not sure what the right solution is for you, but probably a controller or helper method
sanitize(string, options)
is better than doing what you've done. After all, that's what you're calling. - If you have to add a method, don't open the class and clobber like you've done:
module StringSanitizer
def sanitize(...)
super # if appropriate - see if it already exists in the class or if something else has already added it
ActionController::Base.helpers.sanitize(self, options)
end
end
String.prepend(StringSanitizer)
答案2
得分: 0
这是我根据 @kwerle 的建议制定的解决方案:
module Sanitizable
extend ActiveSupport::Concern
class_methods do
def sanitizable(*attributes)
before_save do |record|
attributes.each do |attribute|
record[attribute] = ActionController::Base.helpers.sanitize(record[attribute], tags: %w(p span strong b em i br ol ul li))
end
end
end
end
end
这可以在模型中使用:
include Sanitizable
sanitizable :subtitle, :description
英文:
Here's the solution I came with following @kwerle 's recommendations:
module Sanitizable
extend ActiveSupport::Concern
class_methods do
def sanitizable(*attributes)
before_save do |record|
attributes.each do |attribute|
record[attribute] = ActionController::Base.helpers.sanitize(record[attribute], tags: %w(p span strong b em i br ol ul li))
end
end
end
end
end
and this can be used in a model with:
include Sanitizable
sanitizable :subtitle, :description
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论