Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connecting via unix socket on a specific DB crashes pgcli #1422

Open
3 tasks done
P-EB opened this issue Oct 5, 2023 · 3 comments
Open
3 tasks done

Connecting via unix socket on a specific DB crashes pgcli #1422

P-EB opened this issue Oct 5, 2023 · 3 comments

Comments

@P-EB
Copy link

P-EB commented Oct 5, 2023

Description

Hello

Installing pgcli 3.5.0 on a Debian server with postgresql 15, when, as unix user postgres, I run a simple pgcli, I get a proper prompt, but as soon as I use pgcli XXX with XXXbeing another database, pgcli crashes while starting because it tries to mix str and bytes.

postgres@pgsql:~$ pgcli                                                             
Server: PostgreSQL 15.3 (Debian 15.3-0+deb12u1)
Version: 3.5.0            
Home: http://pgcli.com                                                                                                                                                     
postgres>                                                                                                                                                                                                                                                                                                                                             
Goodbye!                      
postgres@pgsql:~$ pgcli icinga2                                                                                                                                            
Server: PostgreSQL 15.3 (Debian 15.3-0+deb12u1)
Version: 3.5.0                                                                                                                                                             
Home: http://pgcli.com                     
Traceback (most recent call last):                                                                                                                                         
  File "/usr/bin/pgcli", line 33, in <module>
Exception in thread completion_refresh:                                                                                                                                    
Traceback (most recent call last):                                       
  File "/usr/lib/python3.11/threading.py", line 1038, in _bootstrap_inner
    sys.exit(load_entry_point('pgcli==3.5.0', 'console_scripts', 'pgcli')())                                                                                               
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/click/core.py", line 1130, in __call__
    self.run()                                                                                                                                                             
  File "/usr/lib/python3.11/threading.py", line 975, in run                    
    return self.main(*args, **kwargs)              
           ^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                                      
  File "/usr/lib/python3/dist-packages/click/core.py", line 1055, in main
    rv = self.invoke(ctx)                                            
         ^^^^^^^^^^^^^^^^                                                                                                                                                  
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3/dist-packages/pgcli/completion_refresher.py", line 68, in _bg_refresh
  File "/usr/lib/python3/dist-packages/click/core.py", line 1404, in invoke                                                                                                
    refresher(completer, executor)                                             
  File "/usr/lib/python3/dist-packages/pgcli/completion_refresher.py", line 109, in refresh_schemata
    return ctx.invoke(self.callback, **ctx.params)                                                                                                                         
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/click/core.py", line 760, in invoke
    completer.set_search_path(executor.search_path())                                                                                                                      
  File "/usr/lib/python3/dist-packages/pgcli/pgcompleter.py", line 306, in set_search_path
    return __callback(*args, **kwargs)
    self.search_path = self.escaped_names(search_path)                                                                                                                     
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^          
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/pgcli/main.py", line 1427, in cli                                                                                                   
  File "/usr/lib/python3/dist-packages/pgcli/pgcompleter.py", line 150, in escaped_names
    return [self.escape_name(name) for name in names]           
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^                                                                                                                      
  File "/usr/lib/python3/dist-packages/pgcli/pgcompleter.py", line 150, in <listcomp> 
    pgcli.run_cli()                 
  File "/usr/lib/python3/dist-packages/pgcli/main.py", line 788, in run_cli    
    return [self.escape_name(name) for name in names]
            ^^^^^^^^^^^^^^^^^^^^^^         
  File "/usr/lib/python3/dist-packages/pgcli/pgcompleter.py", line 131, in escape_name
    text = self.prompt_app.prompt()                                
           ^^^^^^^^^^^^^^^^^^^^^^^^                                
  File "/usr/lib/python3/dist-packages/prompt_toolkit/shortcuts/prompt.py", line 1034, in prompt
    (not self.name_pattern.match(name))

TypeError: cannot use a string pattern on a bytes-like object
    return self.app.run(          
           ^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/application/application.py", line 978, in run
    return loop.run_until_complete(
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/asyncio/base_events.py", line 653, in run_until_complete
    return future.result()                                           
           ^^^^^^^^^^^^^^^      
  File "/usr/lib/python3/dist-packages/prompt_toolkit/application/application.py", line 885, in run_async
    return await _run_async(f)
           ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/application/application.py", line 743, in _run_async
    self._redraw()
  File "/usr/lib/python3/dist-packages/prompt_toolkit/application/application.py", line 557, in _redraw
    self.context.copy().run(run_in_context)
  File "/usr/lib/python3/dist-packages/prompt_toolkit/application/application.py", line 540, in run_in_context
    self.renderer.render(self, self.layout)
  File "/usr/lib/python3/dist-packages/prompt_toolkit/renderer.py", line 640, in render
    layout.container.preferred_height(size.columns, size.rows).preferred,
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/layout/containers.py", line 326, in preferred_height
    dimensions = [
                 ^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/layout/containers.py", line 327, in <listcomp>
    c.preferred_height(width, max_available_height) for c in self._all_children
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/layout/containers.py", line 796, in preferred_height
    return self.content.preferred_height(width, max_available_height)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/layout/containers.py", line 326, in preferred_height
    dimensions = [
                 ^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/layout/containers.py", line 327, in <listcomp>
    c.preferred_height(width, max_available_height) for c in self._all_children
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/layout/containers.py", line 2642, in preferred_height
    if self.filter():
       ^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/filters/base.py", line 210, in __call__
    return self.func()
           ^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/shortcuts/prompt.py", line 168, in has_before_fragments
    for fragment, char, *_ in get_prompt_text():
                              ^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/shortcuts/prompt.py", line 1279, in _get_prompt
    return to_formatted_text(self.message, style="class:prompt")
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/prompt_toolkit/formatted_text/base.py", line 81, in to_formatted_text
    return to_formatted_text(value(), style=style)
                             ^^^^^^^
  File "/usr/lib/python3/dist-packages/pgcli/main.py", line 851, in get_message
    prompt = self.get_prompt(prompt_format)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/pgcli/main.py", line 1115, in get_prompt
    string = string.replace("\\H", self.pgexecute.host or "(none)")
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: replace() argument 2 must be str, not bytes
postgres@pgsql:~$ ;1R

As you see, there are two type errors, and both relate to mixing str and bytes.

After poking a bit, it seems that when I give another database as an argument, pgcli connects to it and then makes queries to the postgres database to get the unix socket configuration and other stufs from the pg_settings database. In the case of a connection to the postgres database, the cursor fetches strings (eg in pgexecute.get_socket_directory function), while when connected to another database, the cursor fetches bytes.

I think some sanitizing is needed.

Your environment

  • Please provide your OS and version information. Debian 12
  • Please provide your CLI version. 3.5.0
  • What is the output of pip freeze command: nothing, I don't use pip. psycopg version is 3.1.7
@j-bennet
Copy link
Contributor

j-bennet commented Oct 7, 2023

@P-EB Thank you for reporting. What's the python version, and how did you install pgcli (you said it was not pip)?

@P-EB
Copy link
Author

P-EB commented Oct 9, 2023

Via apt, as I'm using Debian.

Python3 version is 3.11.5

@P-EB
Copy link
Author

P-EB commented Oct 13, 2023

@j-bennet in case you did not see it I replied to your question.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants