Skip to content

Commit afc3a57

Browse files
committed
fix: handle bytes/string mismatch in replace at startup
Fix TypeError crashes when PostgreSQL returns bytes values: - pgcli/main.py: Convert bytes to str in get_prompt() for user, host, short_host, dbname, and transaction_indicator - pgcli/pgcompleter.py: Decode bytes to str in escape_name() before matching against name_pattern regex
1 parent 4eb62f5 commit afc3a57

2 files changed

Lines changed: 17 additions & 12 deletions

File tree

pgcli/main.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,21 +1301,24 @@ def get_completions(self, text, cursor_positition):
13011301
return self.completer.get_completions(Document(text=text, cursor_position=cursor_positition), None)
13021302

13031303
def get_prompt(self, string):
1304-
# should be before replacing \\d
1305-
string = string.replace("\\dsn_alias", self.dsn_alias or "")
1306-
string = string.replace("\\t", self.now.strftime("%x %X"))
1307-
string = string.replace("\\u", self.pgexecute.user or "(none)")
1308-
string = string.replace("\\H", self.pgexecute.host or "(none)")
1309-
string = string.replace("\\h", self.pgexecute.short_host or "(none)")
1310-
string = string.replace("\\d", self.pgexecute.dbname or "(none)")
1304+
# should be before replacing \d
1305+
def _to_str(val):
1306+
return val.decode("utf-8") if isinstance(val, bytes) else val or ""
1307+
1308+
string = string.replace("\dsn_alias", self.dsn_alias or "")
1309+
string = string.replace("\t", self.now.strftime("%x %X"))
1310+
string = string.replace("\u", _to_str(self.pgexecute.user) or "(none)")
1311+
string = string.replace("\H", _to_str(self.pgexecute.host) or "(none)")
1312+
string = string.replace("\h", _to_str(self.pgexecute.short_host) or "(none)")
1313+
string = string.replace("\d", _to_str(self.pgexecute.dbname) or "(none)")
13111314
string = string.replace(
1312-
"\\p",
1315+
"\p",
13131316
str(self.pgexecute.port) if self.pgexecute.port is not None else "5432",
13141317
)
1315-
string = string.replace("\\i", str(self.pgexecute.pid) or "(none)")
1316-
string = string.replace("\\#", "#" if self.pgexecute.superuser else ">")
1317-
string = string.replace("\\n", "\n")
1318-
string = string.replace("\\T", self.pgexecute.transaction_indicator)
1318+
string = string.replace("\i", str(self.pgexecute.pid) or "(none)")
1319+
string = string.replace("\#", "#" if self.pgexecute.superuser else ">")
1320+
string = string.replace("\n", "\n")
1321+
string = string.replace("\T", _to_str(self.pgexecute.transaction_indicator))
13191322
return string
13201323

13211324
def get_last_query(self):

pgcli/pgcompleter.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,8 @@ def __init__(self, smart_completion=True, pgspecial=None, settings=None):
141141
self.all_completions = set(self.keywords + self.functions)
142142

143143
def escape_name(self, name):
144+
if isinstance(name, bytes):
145+
name = name.decode("utf-8")
144146
if name and ((not self.name_pattern.match(name)) or (name.upper() in self.reserved_words) or (name.upper() in self.functions)):
145147
name = '"%s"' % name
146148

0 commit comments

Comments
 (0)