diff options
author | Jeremy Kemper <jeremy@bitsweat.net> | 2005-09-26 20:29:01 +0000 |
---|---|---|
committer | Jeremy Kemper <jeremy@bitsweat.net> | 2005-09-26 20:29:01 +0000 |
commit | a5e2f6cd28710e4a81e850a77d5d0833cb1379de (patch) | |
tree | 9eb5a26b5decc6718aa1affe07e5dc3faa7c2abf /activerecord/lib/active_record | |
parent | 79a535ecd7baaa2aa7a87435f95c6ef93b038ced (diff) | |
download | rails-a5e2f6cd28710e4a81e850a77d5d0833cb1379de.tar.gz rails-a5e2f6cd28710e4a81e850a77d5d0833cb1379de.tar.bz2 rails-a5e2f6cd28710e4a81e850a77d5d0833cb1379de.zip |
r3590@asus: jeremy | 2005-09-26 17:00:53 -0700
Correct and optimize PostgreSQL bytea escaping. This is a blend of four patches, each providing a bit to the solution.
git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@2347 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
Diffstat (limited to 'activerecord/lib/active_record')
-rw-r--r-- | activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb | 50 |
1 files changed, 43 insertions, 7 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 254b1a04a8..037f5f6869 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -79,7 +79,7 @@ module ActiveRecord def quote(value, column = nil) if value.class == String && column && column.type == :binary - quote_bytea(value) + "'#{escape_bytea(value)}'" else super end @@ -266,16 +266,52 @@ module ActiveRecord return rows end - def quote_bytea(s) - "'#{escape_bytea(s)}'" - end - def escape_bytea(s) - s.gsub(/\\/) { '\\\\\\\\' }.gsub(/[^\\]/) { |c| sprintf('\\\\%03o', c[0].to_i) } unless s.nil? + if PGconn.respond_to? :escape_bytea + self.class.send(:define_method, :escape_bytea) do |s| + PGconn.escape_bytea(s) if s + end + else + self.class.send(:define_method, :escape_bytea) do |s| + if s + result = '' + s.each_byte { |c| result << sprintf('\\\\%03o', c) } + result + end + end + end + escape_bytea(s) end def unescape_bytea(s) - s.gsub(/\\([0-9][0-9][0-9])/) { $1.oct.chr }.gsub(/\\\\/) { '\\' } unless s.nil? + if PGconn.respond_to? :unescape_bytea + self.class.send(:define_method, :unescape_bytea) do |s| + PGconn.unescape_bytea(s) if s + end + else + self.class.send(:define_method, :unescape_bytea) do |s| + if s + result = '' + i, max = 0, s.size + while i < max + char = s[i] + if char == ?\\ + if s[i+1] == ?\\ + char = ?\\ + i += 1 + else + char = s[i+1..i+3].oct + i += 3 + end + end + result << char + i += 1 + end + result + end + end + end + unescape_bytea(s) end # Query a table's column names, default values, and types. |