It's seems that the function "do_text_output_multiline" does not suit for format "line1\nline2\n...lineN".

From: Hao Lee <mixtrue(at)gmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: It's seems that the function "do_text_output_multiline" does not suit for format "line1\nline2\n...lineN".
Date: 2016-05-20 07:13:03
Message-ID: CAGoxFiFPAGyPAJLcFxTB5cGhTW2yOVBDYeqDugYwV4dEd1L_Ag@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi all,

Today, I am do some works on adding some customized featues to PostgreSQL
9.6 beta1. But, when i do some output to psql using the fuction
"do_text_output_multiline" with the string just like mentioned in mail
tilte, such as "this is a\ntest for\nnew blank.". the PostgreSQL may lead
to corruption in this function, and i debugged it that found this function
can not dealt with the boundaries properly. The original function code as :

do_text_output_multiline(TupOutputState *tstate, char *text)
{
Datum values[1];
bool isnull[1] = {false};

while (*text)
{
char *eol;
int len;

eol = strchr(text, '\n');
if (eol)
{
len = eol - text;

eol++;
}
else
{
len = strlen(text);
eol += len;
}

values[0] = PointerGetDatum(cstring_to_text_with_len(text, len));
do_tup_output(tstate, values, isnull);
pfree(DatumGetPointer(values[0]));
text = eol;
}
}

using the string "this is a*\n*test for*\n*new blank." as the second input
parameter, when dealing with the the last part of stirng, "new blank.", the
code "eol = strchr(text, '\n');" will return NULL and will go into the
"else" part, and the varialbe "eol" will added an integer, which is the
length of "new blank.", eol will be 0xa, text is set to 0xa too. this
address will is a system used address, then corruption. I think some
boundary check will be added as following.

do_text_output_multiline(TupOutputState *tstate, char *text)
{
Datum values[1];
bool isnull[1] = {false};

while (*text *&& *text) //*if the text is NULL the return, do nothing.*
{
char *eol;
int len;

eol = strchr(text, '\n');
if (eol)
{
len = eol - text;

eol++;
}
else
{
len = strlen(text);
* if (eol) //to check whether the eol is NULL or not.*
eol += len;
}

values[0] = PointerGetDatum(cstring_to_text_with_len(text, len));
do_tup_output(tstate, values, isnull);
pfree(DatumGetPointer(values[0]));
text = eol;
}
}

Best Regards.

RingsC.

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Craig Ringer 2016-05-20 07:35:17 Re: foreign table batch inserts
Previous Message Peter Geoghegan 2016-05-20 02:38:02 Re: memory layouts for binary search in nbtree