postgres.git / summary / log / commit / refs

commit    7b40b2d90f44c1f4ef1bc130bd94decb15826676
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Mon May 23 18:16:41 2016 +0000
First released in: 9.6.0, 9.1.23, 9.2.18, 9.3.14, 9.4.9, 9.5.4

    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>


src/backend/executor/execTuples.c | 19 +++++++++---------- src/include/executor/executor.h | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 337e8f84f30..9e959486125 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -1238,33 +1238,32 @@ do_tup_output(TupOutputState *tstate, Datum *values, bool *isnull) * Should only be used with a single-TEXT-attribute tupdesc. */ void -do_text_output_multiline(TupOutputState *tstate, char *text) +do_text_output_multiline(TupOutputState *tstate, const char *txt) { Datum values[1]; bool isnull[1] = {false}; - while (*text) + while (*txt) { - char *eol; + const char *eol; int len; - eol = strchr(text, '\n'); + eol = strchr(txt, '\n'); if (eol) { - len = eol - text; - + len = eol - txt; eol++; } else { - len = strlen(text); - eol += len; + len = strlen(txt); + 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); pfree(DatumGetPointer(values[0])); - text = eol; + txt = eol; } } diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h index 2eb9b1f2538..f23ac463cc0 100644 --- a/src/include/executor/executor.h +++ b/src/include/executor/executor.h @@ -269,7 +269,7 @@ typedef struct TupOutputState extern TupOutputState *begin_tup_output_tupdesc(DestReceiver *dest, TupleDesc tupdesc); 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); /* [parent: 57a72661b4e5]