Fix latent crash in do_text_output_multiline().
do_text_output_multiline() would fail (typically with a null pointer dereference crash) if its input string did not end with a newline. Such cases do not arise in our current sources; but it certainly could happen in future, or in extension code's usage of the function, so we should fix it. To fix, replace "eol += len" with "eol = text + len". While at it, make two cosmetic improvements: mark the input string const, and rename the argument from "text" to "txt" to dodge pgindent strangeness (since "text" is a typedef name). Even though this problem is only latent at present, it seems like a good idea to back-patch the fix, since it's a very simple/safe patch and it's not out of the realm of possibility that we might in future back-patch something that expects sane behavior from do_text_output_multiline(). Per report from Hao Lee. Report: <CAGoxFiFPAGyPAJLcFxTB5cGhTW2yOVBDYeqDugYwV4dEd1L_Ag@mail.gmail.com>
This commit is contained in:
parent
a50b605aa4
commit
8a4930e3fa
@ -1325,33 +1325,32 @@ do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull)
|
|||||||
* Should only be used with a single-TEXT-attribute tupdesc.
|
* Should only be used with a single-TEXT-attribute tupdesc.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
do_text_output_multiline(TupOutputState *tstate, char *text)
|
do_text_output_multiline(TupOutputState *tstate, const char *txt)
|
||||||
{
|
{
|
||||||
Datum values[1];
|
Datum values[1];
|
||||||
bool isnull[1] = {false};
|
bool isnull[1] = {false};
|
||||||
|
|
||||||
while (*text)
|
while (*txt)
|
||||||
{
|
{
|
||||||
char *eol;
|
const char *eol;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
eol = strchr(text, '\n');
|
eol = strchr(txt, '\n');
|
||||||
if (eol)
|
if (eol)
|
||||||
{
|
{
|
||||||
len = eol - text;
|
len = eol - txt;
|
||||||
|
|
||||||
eol++;
|
eol++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
len = strlen(text);
|
len = strlen(txt);
|
||||||
eol += len;
|
eol = txt + len;
|
||||||
}
|
}
|
||||||
|
|
||||||
values[0] = PointerGetDatum(cstring_to_text_with_len(text, len));
|
values[0] = PointerGetDatum(cstring_to_text_with_len(txt, len));
|
||||||
do_tup_output(tstate, values, isnull);
|
do_tup_output(tstate, values, isnull);
|
||||||
pfree(DatumGetPointer(values[0]));
|
pfree(DatumGetPointer(values[0]));
|
||||||
text = eol;
|
txt = eol;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ typedef struct TupOutputState
|
|||||||
extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest,
|
extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest,
|
||||||
TupleDesc tupdesc);
|
TupleDesc tupdesc);
|
||||||
extern void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull);
|
extern void do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull);
|
||||||
extern void do_text_output_multiline(TupOutputState *tstate, char *text);
|
extern void do_text_output_multiline(TupOutputState *tstate, const char *txt);
|
||||||
extern void end_tup_output(TupOutputState *tstate);
|
extern void end_tup_output(TupOutputState *tstate);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user