diff --git a/news/nullsub.rst b/news/nullsub.rst new file mode 100644 index 000000000..beff65e93 --- /dev/null +++ b/news/nullsub.rst @@ -0,0 +1,15 @@ +**Added:** None + +**Changed:** None + +**Deprecated:** None + +**Removed:** None + +**Fixed:** + +* Null bytes handed to Popen are now automatically escaped prior + to running a subprocess. This preevents Popen from issuing + embedded null byte exceptions. + +**Security:** None diff --git a/xonsh/built_ins.py b/xonsh/built_ins.py index 2b5b8a1dd..cc06e47ff 100644 --- a/xonsh/built_ins.py +++ b/xonsh/built_ins.py @@ -498,6 +498,7 @@ class SubprocSpec: kwargs.pop('preexec_fn') p = self.cls(self.alias, self.cmd, **kwargs) else: + self._fix_null_cmd_bytes() p = self._run_binary(kwargs) p.spec = self p.last_in_pipeline = self.last_in_pipeline @@ -546,6 +547,14 @@ class SubprocSpec: signal.signal(signal.SIGTSTP, default_signal_pauser) kwargs['preexec_fn'] = xonsh_preexec_fn + def _fix_null_cmd_bytes(self): + # Popen does not accept null bytes in its input commands. + # that doesn;t stop some subproces from using them. Here we + # escape them just in case. + cmd = self.cmd + for i in range(len(cmd)): + cmd[i] = cmd[i].replace('\0', '\\0') + # # Building methods #