checks_attribute_values_and_length.rb 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. module ApplicationModel::ChecksAttributeValuesAndLength
  3. extend ActiveSupport::Concern
  4. included do
  5. before_create :check_attribute_values_and_length
  6. before_update :check_attribute_values_and_length
  7. end
  8. =begin
  9. 1) check string/varchar size and cut them if needed
  10. 2) check string for null byte \u0000 and remove it
  11. =end
  12. def check_attribute_values_and_length
  13. columns = self.class.columns_hash
  14. attributes.each do |name, value|
  15. next if !value.instance_of?(String)
  16. column = columns[name]
  17. next if !column
  18. if column.type == :binary
  19. self[name].force_encoding('BINARY')
  20. end
  21. next if value.blank?
  22. # strip null byte chars (postgresql will complain about it)
  23. if column.type == :text && Rails.application.config.db_null_byte == false
  24. self[name].delete!("\u0000")
  25. end
  26. # for varchar check length and replace null bytes
  27. limit = column.limit
  28. if limit
  29. current_length = value.length
  30. if limit < current_length
  31. logger.warn "WARNING: cut string because of database length #{self.class}.#{name}(#{limit} but is #{current_length}:#{value})"
  32. self[name] = value[0, limit]
  33. end
  34. # strip null byte chars (postgresql will complain about it)
  35. if Rails.application.config.db_null_byte == false
  36. self[name].delete!("\u0000")
  37. end
  38. end
  39. # strip 4 bytes utf8 chars if needed (mysql/mariadb will complain it)
  40. next if self[name].blank?
  41. next if column.type == :binary
  42. self[name] = self[name].utf8_to_3bytesutf8
  43. end
  44. true
  45. end
  46. end