From f242a81b81f2010e90f575d6987ef2d8b15a493f Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Wed, 21 Oct 2026 10:34:44 -0400 Subject: [PATCH] psql: Fall back to English for unsafe hidden query labels. This completes the project begun in commit 294d2196c of making commit 41d69e6dc's hidden query labels safe against unexpected encoding-related failures. At that point we were still uncertain exactly what rule to use to decide that a translated label is safe. The rule adopted here is: translate the label only when the client and server encodings match and the translated bytes pass the same encoding verification check the server will apply. This is enough to ensure that no error will be thrown, and it avoids the difficult task of identifying what encoding gettext() thinks it's using. Author: shihao zhong Reviewed-by: Fujii Masao Reviewed-by: Tom Lane Discussion: https://postgr.es/m/CAGRkXqRv7yhBOhF0YvSr6ZB7rvsPCjnXSPj8=3bKcSJuYvNrBA@mail.gmail.com Backpatch-through: 19 --- src/bin/psql/common.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/bin/psql/common.c b/src/bin/psql/common.c index 6d4cbcad806..5b7f232ee70 100644 --- a/src/bin/psql/common.c +++ b/src/bin/psql/common.c @@ -28,6 +28,7 @@ #include "fe_utils/mbprint.h" #include "fe_utils/string_utils.h" #include "mainloop.h" +#include "mb/pg_wchar.h" #include "portability/instr_time.h" #include "settings.h" @@ -2631,8 +2632,28 @@ void addQueryComment(PQExpBuffer buf, const char *label) { #if defined(ENABLE_NLS) - /* This will become conditional once we've settled on the tests to use */ - label = _(label); + const char *server_enc = PQparameterStatus(pset.db, "server_encoding"); + int client_enc = PQclientEncoding(pset.db); + + /* + * We must skip translation if it would cause the server to reject the + * query due to an encoding conversion/verification failure. For now it + * seems sufficient to handle only the case of equal client and server + * encodings: then the server just verifies the string in that encoding, + * and we can run the same check here. It's necessary to check for this + * because we can't be 100% sure which encoding gettext() thinks it should + * produce. If it is indeed different from our client encoding, the + * result may look like junk to a human, but it won't cause an error. + */ + if (server_enc != NULL && + pg_char_to_encoding(server_enc) == client_enc) + { + const char *translated = _(label); + int len = strlen(translated); + + if (pg_encoding_verifymbstr(client_enc, translated, len) == len) + label = translated; + } #endif printfPQExpBuffer(buf, "/* %s */\n", label);