Re: BUG #8702: psql \df+ translate_columns[] overflow and unexpected gettext translation - Mailing list pgsql-bugs
| From | Tom Lane |
|---|---|
| Subject | Re: BUG #8702: psql \df+ translate_columns[] overflow and unexpected gettext translation |
| Date | |
| Msg-id | 668.1388444467@sss.pgh.pa.us Whole thread Raw |
| In response to | Re: BUG #8702: psql \df+ translate_columns[] overflow and unexpected gettext translation (Peter Eisentraut <peter_e@gmx.net>) |
| Responses |
Re: BUG #8702: psql \df+ translate_columns[] overflow and unexpected gettext translation
|
| List | pgsql-bugs |
Peter Eisentraut <peter_e@gmx.net> writes:
> There are several places that are similarly broken. See attached patch.
> Obviously, this is not a very robust programming interface, if the same
> mistake has been repeated three times independently.
Yeah :-(. How about adding an Assert as in the attached?
I had to make the Assert say ">=" not just "==" because there are numerous
callers that use the same array for both normal and verbose output.
This seems a bit shaky but it's not actually broken anywhere.
I think.
The breakage in \df appears to be the fault of the addition of a
translated "security definer/invoker" column, which clearly nobody really
tested the translations for, or they'd have noticed that the column
marking in translate_columns[] was wrong :-(. I believe the "translation
support" in \dy (event triggers) is pretty bogus as well.
regards, tom lane
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 96322ca..e915262 100644
*** a/src/bin/psql/describe.c
--- b/src/bin/psql/describe.c
*************** describeFunctions(const char *functypes,
*** 224,230 ****
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
! static const bool translate_columns[] = {false, false, false, false, true, true, false, false, false, false};
if (strlen(functypes) != strspn(functypes, "antwS+"))
{
--- 224,230 ----
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
! static const bool translate_columns[] = {false, false, false, false, true, true, true, false, false, false,
false};
if (strlen(functypes) != strspn(functypes, "antwS+"))
{
*************** describeFunctions(const char *functypes,
*** 457,462 ****
--- 457,463 ----
myopt.title = _("List of functions");
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
printQuery(res, &myopt, pset.queryFout, pset.logfile);
*************** permissionsList(const char *pattern)
*** 789,794 ****
--- 790,796 ----
myopt.title = buf.data;
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
printQuery(res, &myopt, pset.queryFout, pset.logfile);
*************** listDefaultACLs(const char *pattern)
*** 862,867 ****
--- 864,870 ----
myopt.title = buf.data;
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
printQuery(res, &myopt, pset.queryFout, pset.logfile);
*************** objectDescription(const char *pattern, b
*** 1034,1039 ****
--- 1037,1043 ----
myopt.title = _("Object descriptions");
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
printQuery(res, &myopt, pset.queryFout, pset.logfile);
*************** listTables(const char *tabtypes, const c
*** 2818,2823 ****
--- 2822,2828 ----
myopt.title = _("List of relations");
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
printQuery(res, &myopt, pset.queryFout, pset.logfile);
}
*************** listConversions(const char *pattern, boo
*** 2999,3005 ****
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
! static const bool translate_columns[] = {false, false, false, false, true};
initPQExpBuffer(&buf);
--- 3004,3011 ----
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
! static const bool translate_columns[] =
! {false, false, false, false, true, false};
initPQExpBuffer(&buf);
*************** listConversions(const char *pattern, boo
*** 3055,3060 ****
--- 3061,3067 ----
myopt.title = _("List of conversions");
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
printQuery(res, &myopt, pset.queryFout, pset.logfile);
*************** listEventTriggers(const char *pattern, b
*** 3116,3121 ****
--- 3123,3129 ----
myopt.title = _("List of event triggers");
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
printQuery(res, &myopt, pset.queryFout, pset.logfile);
*************** listCasts(const char *pattern, bool verb
*** 3134,3140 ****
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
! static const bool translate_columns[] = {false, false, false, true};
initPQExpBuffer(&buf);
--- 3142,3148 ----
PQExpBufferData buf;
PGresult *res;
printQueryOpt myopt = pset.popt;
! static const bool translate_columns[] = {false, false, false, true, false};
initPQExpBuffer(&buf);
*************** listCasts(const char *pattern, bool verb
*** 3214,3219 ****
--- 3222,3228 ----
myopt.title = _("List of casts");
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
printQuery(res, &myopt, pset.queryFout, pset.logfile);
*************** listCollations(const char *pattern, bool
*** 3289,3294 ****
--- 3298,3304 ----
myopt.title = _("List of collations");
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
printQuery(res, &myopt, pset.queryFout, pset.logfile);
*************** describeOneTSParser(const char *oid, con
*** 3548,3553 ****
--- 3558,3564 ----
myopt.topt.default_footer = false;
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
+ myopt.n_translate_columns = lengthof(translate_columns);
printQuery(res, &myopt, pset.queryFout, pset.logfile);
*************** describeOneTSParser(const char *oid, con
*** 3579,3584 ****
--- 3590,3596 ----
myopt.topt.default_footer = true;
myopt.translate_header = true;
myopt.translate_columns = NULL;
+ myopt.n_translate_columns = 0;
printQuery(res, &myopt, pset.queryFout, pset.logfile);
diff --git a/src/bin/psql/print.c b/src/bin/psql/print.c
index 736225c..fdf4dcc 100644
*** a/src/bin/psql/print.c
--- b/src/bin/psql/print.c
*************** printQuery(const PGresult *result, const
*** 2596,2601 ****
--- 2596,2605 ----
printTableInit(&cont, &opt->topt, opt->title,
PQnfields(result), PQntuples(result));
+ /* Assert caller supplied enough translate_columns[] entries */
+ Assert(opt->translate_columns == NULL ||
+ opt->n_translate_columns >= cont.ncolumns);
+
for (i = 0; i < cont.ncolumns; i++)
{
char align;
diff --git a/src/bin/psql/print.h b/src/bin/psql/print.h
index 9cfa3b6..41ba798 100644
*** a/src/bin/psql/print.h
--- b/src/bin/psql/print.h
*************** typedef struct printQueryOpt
*** 146,151 ****
--- 146,152 ----
bool translate_header; /* do gettext on column headers */
const bool *translate_columns; /* translate_columns[i-1] => do
* gettext on col i */
+ int n_translate_columns; /* length of translate_columns[] */
} printQueryOpt;
diff --git a/src/bin/scripts/createlang.c b/src/bin/scripts/createlang.c
index 5cfba8e..92ab975 100644
*** a/src/bin/scripts/createlang.c
--- b/src/bin/scripts/createlang.c
*************** main(int argc, char *argv[])
*** 160,165 ****
--- 160,167 ----
popt.title = _("Procedural Languages");
popt.translate_header = true;
popt.translate_columns = translate_columns;
+ popt.n_translate_columns = lengthof(translate_columns);
+
printQuery(result, &popt, stdout, NULL);
PQfinish(conn);
diff --git a/src/bin/scripts/droplang.c b/src/bin/scripts/droplang.c
index b9664a9..3650096 100644
*** a/src/bin/scripts/droplang.c
--- b/src/bin/scripts/droplang.c
*************** main(int argc, char *argv[])
*** 159,164 ****
--- 159,166 ----
popt.title = _("Procedural Languages");
popt.translate_header = true;
popt.translate_columns = translate_columns;
+ popt.n_translate_columns = lengthof(translate_columns);
+
printQuery(result, &popt, stdout, NULL);
PQfinish(conn);
pgsql-bugs by date: