Skip to content

Commit 19f3266

Browse files
committed
Use correct text domain for errcontext() appearing within ereport().
The mechanism added in commit dbdf967 for associating the correct translation domain with errcontext strings potentially fails in cases where errcontext() is used within an ereport() macro. Such usage was not originally envisioned for errcontext(), but we do have a few places that do it. In this situation, the intended comma expression becomes just a couple of arguments to errfinish(), which the compiler might choose to evaluate right-to-left. Fortunately, in such cases the textdomain for the errcontext string must be the same as for the surrounding ereport. So we can fix this by letting errstart initialize context_domain along with domain; then it will have the correct value no matter which order the calls occur in. (Note that error stack callback functions are not invoked until errfinish, so normal usage of errcontext won't affect what happens for errcontext calls within the ereport macro.) In passing, make sure that errcontext calls within the main backend set context_domain to something non-NULL. This isn't a live bug because NULL would select the current textdomain() setting which should be the right thing anyway --- but it seems better to handle this completely consistently with the regular domain field. Per report from Dmitry Voronin. Backpatch to 9.3; before that, there wasn't any attempt to ensure that errcontext strings were translated in an appropriate domain.
1 parent e711119 commit 19f3266

File tree

1 file changed

+15
-2
lines changed

1 file changed

+15
-2
lines changed

src/backend/utils/error/elog.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,8 @@ errstart(int elevel, const char *filename, int lineno,
377377
edata->funcname = funcname;
378378
/* the default text domain is the backend's */
379379
edata->domain = domain ? domain : PG_TEXTDOMAIN("postgres");
380+
/* initialize context_domain the same way (see set_errcontext_domain()) */
381+
edata->context_domain = edata->domain;
380382
/* Select default errcode based on elevel */
381383
if (elevel >= ERROR)
382384
edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
@@ -721,7 +723,7 @@ errcode_for_socket_access(void)
721723
char *fmtbuf; \
722724
StringInfoData buf; \
723725
/* Internationalize the error format string */ \
724-
if (translateit && !in_error_recursion_trouble()) \
726+
if ((translateit) && !in_error_recursion_trouble()) \
725727
fmt = dgettext((domain), fmt); \
726728
/* Expand %m in format string */ \
727729
fmtbuf = expand_fmt_string(fmt, edata); \
@@ -1019,6 +1021,16 @@ errcontext_msg(const char *fmt,...)
10191021
* translate it. Instead, each errcontext_msg() call should be preceded by
10201022
* a set_errcontext_domain() call to specify the domain. This is usually
10211023
* done transparently by the errcontext() macro.
1024+
*
1025+
* Although errcontext is primarily meant for use at call sites distant from
1026+
* the original ereport call, there are a few places that invoke errcontext
1027+
* within ereport. The expansion of errcontext as a comma expression calling
1028+
* set_errcontext_domain then errcontext_msg is problematic in this case,
1029+
* because the intended comma expression becomes two arguments to errfinish,
1030+
* which the compiler is at liberty to evaluate in either order. But in
1031+
* such a case, the set_errcontext_domain calls must be selecting the same
1032+
* TEXTDOMAIN value that the errstart call did, so order does not matter
1033+
* so long as errstart initializes context_domain along with domain.
10221034
*/
10231035
int
10241036
set_errcontext_domain(const char *domain)
@@ -1028,7 +1040,8 @@ set_errcontext_domain(const char *domain)
10281040
/* we don't bother incrementing recursion_depth */
10291041
CHECK_STACK_DEPTH();
10301042

1031-
edata->context_domain = domain;
1043+
/* the default text domain is the backend's */
1044+
edata->context_domain = domain ? domain : PG_TEXTDOMAIN("postgres");
10321045

10331046
return 0; /* return value does not matter */
10341047
}

0 commit comments

Comments
 (0)