Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

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
  • Loading branch information...
commit a5e2f6cd28710e4a81e850a77d5d0833cb1379de 1 parent 79a535e
Jeremy Kemper jeremy authored
50 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
View
@@ -79,7 +79,7 @@ def supports_migrations?
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 @@ def select(sql, name = nil)
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.
Please sign in to comment.
Something went wrong with that request. Please try again.