Skip to content

Commit

Permalink
Ensure memory allocated by PQunescapeBytea() is always freed
Browse files Browse the repository at this point in the history
.. even if rb_tainted_str_new() raises an Exception.

Related to issue ged#279.
  • Loading branch information
larskanis committed Jun 25, 2018
1 parent 7e33ea0 commit 08b862f
Showing 1 changed file with 16 additions and 9 deletions.
25 changes: 16 additions & 9 deletions ext/pg_text_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,16 @@ pg_text_dec_float(t_pg_coder *conv, const char *val, int len, int tuple, int fie
return rb_float_new(strtod(val, NULL));
}

struct pg_blob_initialization {
char *blob_string;
size_t length;
};

static VALUE pg_create_blob(VALUE v) {
struct pg_blob_initialization *bi = (struct pg_blob_initialization *)v;
return rb_tainted_str_new(bi->blob_string, bi->length);
}

/*
* Document-class: PG::TextDecoder::Bytea < PG::SimpleDecoder
*
Expand All @@ -193,16 +203,13 @@ pg_text_dec_float(t_pg_coder *conv, const char *val, int len, int tuple, int fie
static VALUE
pg_text_dec_bytea(t_pg_coder *conv, const char *val, int len, int tuple, int field, int enc_idx)
{
unsigned char *to;
size_t to_len;
VALUE ret;

to = PQunescapeBytea( (unsigned char *)val, &to_len);
struct pg_blob_initialization bi;

ret = rb_tainted_str_new((char*)to, to_len);
PQfreemem(to);

return ret;
bi.blob_string = (char *)PQunescapeBytea((unsigned char*)val, &bi.length);
if (bi.blob_string == NULL) {
rb_raise(rb_eNoMemError, "PQunescapeBytea failure: probably not enough memory");
}
return rb_ensure(pg_create_blob, (VALUE)&bi, (VALUE(*)())PQfreemem, (VALUE)bi.blob_string);
}

/*
Expand Down

0 comments on commit 08b862f

Please sign in to comment.