You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
pg uses xmalloc/free for the temporary buffer for array elements, without using rb_ensure to ensure that free is called if an exception is raised by decoding. This means if a decoder raises an error, the memory is leaked. Example test case:
#!ruby
require 'pg'
conn = PG.connect
class ByteaLeaker < PG::SimpleDecoder
def decode(string, tuple=nil, field=nil)
raise
end
end
PG::BasicTypeRegistry.register_type(0, 'bytea', nil, ByteaLeaker)
map = conn.type_map_for_results = PG::BasicTypeMapForResults.new(conn)
GC.start
system("ps aux -p #{$$}")
100.times do
print '.'
res = nil
begin
res = conn.exec("SELECT ARRAY['#{'a'*1000000}']::bytea[]")
res.getvalue(0,0)
rescue RuntimeError
ensure
res.clear if res
end
end
GC.start
system("ps aux -p #{$$}")
FYI, sequel_pg uses rb_str_buf_new for the temporary buffer to avoid needing rb_ensure, but make sure you use RB_GC_GUARD appropriately if you do that.
There is a similar leak in pg_text_dec_bytea, where the buffer returned by PQunescapeBytea is leaked if rb_tainted_str_new fails. That's harder to hit, but if you are out of memory, leaking memory is going to make things worse. sequel_pg now uses rb_ensure in that case to avoid leaking memory.
The text was updated successfully, but these errors were encountered:
Original report by Jeremy Evans (Bitbucket: jeremyevans, GitHub: jeremyevans).
pg uses xmalloc/free for the temporary buffer for array elements, without using rb_ensure to ensure that free is called if an exception is raised by decoding. This means if a decoder raises an error, the memory is leaked. Example test case:
FYI, sequel_pg uses rb_str_buf_new for the temporary buffer to avoid needing rb_ensure, but make sure you use RB_GC_GUARD appropriately if you do that.
There is a similar leak in pg_text_dec_bytea, where the buffer returned by PQunescapeBytea is leaked if rb_tainted_str_new fails. That's harder to hit, but if you are out of memory, leaking memory is going to make things worse. sequel_pg now uses rb_ensure in that case to avoid leaking memory.
The text was updated successfully, but these errors were encountered: