Strip null byte - postgresql will complain about it.
This commit is contained in:
parent
79a089f55b
commit
b10ee11c86
7 changed files with 92 additions and 40 deletions
|
@ -5,7 +5,7 @@ class ApplicationModel < ActiveRecord::Base
|
||||||
include ApplicationModel::HasCache
|
include ApplicationModel::HasCache
|
||||||
include ApplicationModel::CanLookup
|
include ApplicationModel::CanLookup
|
||||||
include ApplicationModel::CanLookupSearchIndexAttributes
|
include ApplicationModel::CanLookupSearchIndexAttributes
|
||||||
include ApplicationModel::ChecksAttributeLength
|
include ApplicationModel::ChecksAttributeValuesAndLength
|
||||||
include ApplicationModel::CanCleanupParam
|
include ApplicationModel::CanCleanupParam
|
||||||
include ApplicationModel::HasRecentViews
|
include ApplicationModel::HasRecentViews
|
||||||
include ApplicationModel::ChecksUserColumnsFillup
|
include ApplicationModel::ChecksUserColumnsFillup
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
|
||||||
module ApplicationModel::ChecksAttributeLength
|
|
||||||
extend ActiveSupport::Concern
|
|
||||||
|
|
||||||
included do
|
|
||||||
before_create :check_attribute_length
|
|
||||||
before_update :check_attribute_length
|
|
||||||
end
|
|
||||||
|
|
||||||
=begin
|
|
||||||
|
|
||||||
check string/varchar size and cut them if needed
|
|
||||||
|
|
||||||
=end
|
|
||||||
|
|
||||||
def check_attribute_length
|
|
||||||
attributes.each { |attribute|
|
|
||||||
next if !self[ attribute[0] ]
|
|
||||||
next if !self[ attribute[0] ].instance_of?(String)
|
|
||||||
next if self[ attribute[0] ].empty?
|
|
||||||
column = self.class.columns_hash[ attribute[0] ]
|
|
||||||
next if !column
|
|
||||||
limit = column.limit
|
|
||||||
if column && limit
|
|
||||||
current_length = attribute[1].to_s.length
|
|
||||||
if limit < current_length
|
|
||||||
logger.warn "WARNING: cut string because of database length #{self.class}.#{attribute[0]}(#{limit} but is #{current_length}:#{attribute[1]})"
|
|
||||||
self[ attribute[0] ] = attribute[1][ 0, limit ]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# strip 4 bytes utf8 chars if needed
|
|
||||||
if column && self[ attribute[0] ]
|
|
||||||
self[attribute[0]] = self[ attribute[0] ].utf8_to_3bytesutf8
|
|
||||||
end
|
|
||||||
}
|
|
||||||
true
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
# Copyright (C) 2012-2016 Zammad Foundation, http://zammad-foundation.org/
|
||||||
|
module ApplicationModel::ChecksAttributeValuesAndLength
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
before_create :check_attribute_values_and_length
|
||||||
|
before_update :check_attribute_values_and_length
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
1) check string/varchar size and cut them if needed
|
||||||
|
|
||||||
|
2) check string for null byte \u0000 and remove it
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def check_attribute_values_and_length
|
||||||
|
columns = self.class.columns_hash
|
||||||
|
attributes.each { |name, value|
|
||||||
|
next if value.blank?
|
||||||
|
next if !value.instance_of?(String)
|
||||||
|
column = columns[name]
|
||||||
|
next if !column
|
||||||
|
|
||||||
|
# strip null byte chars (postgresql will complain about it)
|
||||||
|
if column.sql_type == 'text'
|
||||||
|
if Rails.application.config.db_null_byte == false
|
||||||
|
self[name].delete!("\u0000")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# for varchar check length and replace null bytes
|
||||||
|
limit = column.limit
|
||||||
|
if limit
|
||||||
|
current_length = value.length
|
||||||
|
if limit < current_length
|
||||||
|
logger.warn "WARNING: cut string because of database length #{self.class}.#{name}(#{limit} but is #{current_length}:#{value})"
|
||||||
|
self[name] = value[0, limit]
|
||||||
|
end
|
||||||
|
|
||||||
|
# strip null byte chars (postgresql will complain about it)
|
||||||
|
if Rails.application.config.db_null_byte == false
|
||||||
|
self[name].delete!("\u0000")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# strip 4 bytes utf8 chars if needed (mysql/mariadb will complain it)
|
||||||
|
next if self[name].blank?
|
||||||
|
self[name] = self[name].utf8_to_3bytesutf8
|
||||||
|
}
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,7 @@
|
||||||
# mysql
|
# mysql
|
||||||
if ActiveRecord::Base.connection_config[:adapter] == 'mysql2'
|
if ActiveRecord::Base.connection_config[:adapter] == 'mysql2'
|
||||||
Rails.application.config.db_4bytes_utf8 = false
|
Rails.application.config.db_4bytes_utf8 = false
|
||||||
|
Rails.application.config.db_null_byte = true
|
||||||
|
|
||||||
# mysql version check
|
# mysql version check
|
||||||
# mysql example: "5.7.3"
|
# mysql example: "5.7.3"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
if ActiveRecord::Base.connection_config[:adapter] == 'postgresql'
|
if ActiveRecord::Base.connection_config[:adapter] == 'postgresql'
|
||||||
Rails.application.config.db_case_sensitive = true
|
Rails.application.config.db_case_sensitive = true
|
||||||
Rails.application.config.db_like = 'ILIKE'
|
Rails.application.config.db_like = 'ILIKE'
|
||||||
|
Rails.application.config.db_null_byte = false
|
||||||
|
|
||||||
# postgresql version check
|
# postgresql version check
|
||||||
# example output: "9.5.0"
|
# example output: "9.5.0"
|
||||||
|
|
|
@ -66,6 +66,7 @@ class Stats::TicketReopen
|
||||||
def self.log(object, o_id, changes, updated_by_id)
|
def self.log(object, o_id, changes, updated_by_id)
|
||||||
return if object != 'Ticket'
|
return if object != 'Ticket'
|
||||||
ticket = Ticket.lookup(id: o_id)
|
ticket = Ticket.lookup(id: o_id)
|
||||||
|
return if !ticket
|
||||||
|
|
||||||
# check if close_at is already set / if not, ticket is not reopend
|
# check if close_at is already set / if not, ticket is not reopend
|
||||||
return if !ticket.close_at
|
return if !ticket.close_at
|
||||||
|
|
34
test/unit/ticket_null_byte_test.rb
Normal file
34
test/unit/ticket_null_byte_test.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# encoding: utf-8
|
||||||
|
require 'test_helper'
|
||||||
|
|
||||||
|
class TicketNullByteTest < ActiveSupport::TestCase
|
||||||
|
test 'null byte test' do
|
||||||
|
ticket1 = Ticket.create!(
|
||||||
|
title: "some title \u0000 123",
|
||||||
|
group: Group.lookup(name: 'Users'),
|
||||||
|
customer_id: 2,
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
assert(ticket1, 'ticket created')
|
||||||
|
|
||||||
|
article1 = Ticket::Article.create!(
|
||||||
|
ticket_id: ticket1.id,
|
||||||
|
from: 'some_customer_com-1@example.com',
|
||||||
|
to: 'some_zammad_com-1@example.com',
|
||||||
|
subject: "com test 1\u0000",
|
||||||
|
message_id: 'some@id_com_1',
|
||||||
|
body: "some\u0000message 123",
|
||||||
|
internal: false,
|
||||||
|
sender: Ticket::Article::Sender.find_by(name: 'Customer'),
|
||||||
|
type: Ticket::Article::Type.find_by(name: 'email'),
|
||||||
|
updated_by_id: 1,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
|
assert(article1, 'ticket created')
|
||||||
|
|
||||||
|
ticket1.destroy!
|
||||||
|
article1.destroy!
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue