admin管理员组文章数量:1278825
I have a Rails application using Postgres as the database.
Postrgres does not accept strings containing null bytes (example: "a \u0000 b"
). Trying to save such data leads to the following error:
ActiveRecord::StatementInvalid
PG::UntranslatableCharacter: ERROR: unsupported Unicode escape sequence
I'd like to set up a rule that would work for all of my ActiveRecord models, ensuring that every string attribute would remove null bytes from it before saving. I'm thinking of something that could have an effect similar to the example below:
class MyModel < ApplicationRecord
before_save :remove_null_bytes
private
def remove_null_bytes
my_field.delete!("\u0000")
end
end
But applied to every string attribute of every model without being forced to set this repeatedly.
The reason I want this to be limited to Active Record string attributes is that the application also handles binary uploads and email webhooks. These might contain legit null bytes, and I do not want these to be affected by the new rule.
I have a Rails application using Postgres as the database.
Postrgres does not accept strings containing null bytes (example: "a \u0000 b"
). Trying to save such data leads to the following error:
ActiveRecord::StatementInvalid
PG::UntranslatableCharacter: ERROR: unsupported Unicode escape sequence
I'd like to set up a rule that would work for all of my ActiveRecord models, ensuring that every string attribute would remove null bytes from it before saving. I'm thinking of something that could have an effect similar to the example below:
class MyModel < ApplicationRecord
before_save :remove_null_bytes
private
def remove_null_bytes
my_field.delete!("\u0000")
end
end
But applied to every string attribute of every model without being forced to set this repeatedly.
The reason I want this to be limited to Active Record string attributes is that the application also handles binary uploads and email webhooks. These might contain legit null bytes, and I do not want these to be affected by the new rule.
Share Improve this question asked Feb 24 at 22:05 lmtaqlmtaq 4563 silver badges13 bronze badges 1 |3 Answers
Reset to default 4When you want to normalize all string type attributes on all models, then I would add this to ApplicationRecord
:
class ApplicationRecord < ActiveRecord::Base
normalizes *attribute_names,
with: ->(value) { value.delete("\u0000") if value.is_a?(String) }
end
Note that normalizes
was introduced in Ruby on Rails 7.1 and is not available on older versions.
I'm thinking about setting something like this on ApplicationRecord
:
class ApplicationRecord < ActiveRecord::Base
before_save :remove_null_bytes
def remove_null_bytes
changes.keys.each do |attribute_name|
attr_type = type_for_attribute(attribute_name).type
send(attribute_name).delete!("\u0000") if attr_type == :string
end
end
end
Not sure I'm happy about the metaprogramming and the lack of readability on this approach though
Override write_attribute in ApplicationRecord to ensure that any string attributes are sanitized when assigned:
no need to add before_save method
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
def write_attribute(attr_name, value)
column = self.class.columns_hash[attr_name.to_s]
if column&.type == :string && value.is_a?(String)
value = value.delete("\u0000")
end
super(attr_name, value)
end
end
本文标签: ruby on railsRemove null bytes for every ActiveRecord string attributesStack Overflow
版权声明:本文标题:ruby on rails - Remove null bytes for every ActiveRecord string attributes - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741239445a2363680.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
ActiveRecord::ConnectionAdapters::PostgreSQL::Quoting#quote_string
something as simple as a prepended module definingdef quote_string(s); s.delete!("\u0000"); super(s); end
would likely solve the issue. – engineersmnky Commented Feb 25 at 15:01