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

int data type in env dictionary causes chaos; please catch earlier #664

Open
mmattb opened this issue Oct 21, 2020 · 3 comments
Open

int data type in env dictionary causes chaos; please catch earlier #664

mmattb opened this issue Oct 21, 2020 · 3 comments

Comments

@mmattb
Copy link

mmattb commented Oct 21, 2020

Minimal repro:

In an interactive interpreter:

This is totally fine:
p = pexpect.spawn('env', env={"BLAH": "1"})

This hangs forever; note the int data type on the value
p = pexpect.spawn('env', env={"BLAH": 1})

Killing the above with ctrl+c I get:

p = pexpect.spawn('env', env={"BLAH": 1})
^CTraceback (most recent call last):
File "", line 1, in
File "/home/mbryan/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pexpect/pty_spawn.py", line 205, in init
self._spawn(command, args, preexec_fn, dimensions)
File "/home/mbryan/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pexpect/pty_spawn.py", line 303, in _spawn
self.ptyproc = self._spawnpty(self.args, env=self.env,
File "/home/mbryan/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pexpect/pty_spawn.py", line 315, in _spawnpty
return ptyprocess.PtyProcess.spawn(args, **kwargs)
File "/home/mbryan/.pyenv/versions/3.8.2/lib/python3.8/site-packages/ptyprocess/ptyprocess.py", line 309, in spawn
exec_err_data = os.read(exec_err_pipe_read, 4096)
KeyboardInterrupt

As a somewhat distinct symptom, inside a script you can do:

 import pexpect
  
 p = pexpect.spawn('env', env={"BLAH": 1}) 
  
 try:
    p.expect('asdfasdfas')
 except (pexpect.EOF, pexpect.TIMEOUT):
    print(p.before)

You get:

b'Traceback (most recent call last):\r\n  File "blah2.py", line 3, in <module>\r\n    p = pexpect.spawn(\'env\', env={"BLAH": 1})\r\n  File "/home/mbryan/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pexpect/pty_spawn.py", line 205, in __init__\r\n    self._spawn(command, args, preexec_fn, dimensions)\r\n  File "/home/mbryan/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pexpect/pty_spawn.py", line 303, in _spawn\r\n    self.ptyproc = self._spawnpty(self.args, env=self.env,\r\n  File "/home/mbryan/.pyenv/versions/3.8.2/lib/python3.8/site-packages/pexpect/pty_spawn.py", line 315, in _spawnpty\r\n    return ptyprocess.PtyProcess.spawn(args, **kwargs)\r\n  File "/home/mbryan/.pyenv/versions/3.8.2/lib/python3.8/site-packages/ptyprocess/ptyprocess.py", line 285, in spawn\r\n    os.execvpe(command, argv, env)\r\n  File "/home/mbryan/.pyenv/versions/3.8.2/lib/python3.8/os.py", line 577, in execvpe\r\n    _execvpe(file, args, env)\r\n  File "/home/mbryan/.pyenv/versions/3.8.2/lib/python3.8/os.py", line 591, in _execvpe\r\n    exec_func(file, *argrest)\r\nTypeError: expected str, bytes or os.PathLike object, not int\r\n'

So it seems that there is some sanitization down in the os lib to catch the bad data type, but that we've already borked ourselves before we get there, which means we never print the nastygram; we just exit. Meaning: that traceback should be printed back to the user; it shouldn't end up in the spawn's buffer!

Secondary request: it would be helpful to add some docs for the format of env while you are at it. Maybe there are some on readthedocs, but I'm not seeing them.

@mmattb
Copy link
Author

mmattb commented Oct 21, 2020

Note: I tried this only on Ubuntu 18.04 with Python 3.8.2 and pexpect 4.8.0

@EnigmaticCypher
Copy link

Is there any reason why you would need an int for a value in that dictionary? If not, we could coerce all values inside env to type str. Though that could have unintended consequences. If this is intended behaviour (ie that value is always meant to be a string) then docs could be updated accordingly.

@mmattb
Copy link
Author

mmattb commented Oct 23, 2020

Would the coercion logic affect only the psudo-tty path, or the SSH and other paths as well?
I'm not sure how the data is handled at each layer down the stack, but I'm thinking the user could do something like "1" for an unquoted value, and ""1"" for a quoted value, in theory. But I'm not sure how escaping happens (or doesn't) at lower layers. Do you know? I don't know enough to say.

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