# HG changeset patch # User Yuya Nishihara # Date 2016-11-08 13:22:22 # Node ID ad56204f733ec94e3aceaf0ecd636a05d018a3a3 # Parent a1259e502bdf1188df75e5ef6b1096f676028623 hook: flush stdout before restoring stderr redirection There was a similar issue to 8b011ededfb2. If an in-process hook writes to stdout, the data may be buffered. In which case, stdout must be flushed before restoring its file descriptor. Otherwise, remaining data would be sent over the ssh wire and corrupts the protocol. Note that this is a different redirection from the one I've just removed. diff --git a/mercurial/hook.py b/mercurial/hook.py --- a/mercurial/hook.py +++ b/mercurial/hook.py @@ -258,6 +258,7 @@ def runhooks(ui, repo, name, hooks, thro sys.stderr.flush() finally: if _redirect and oldstdout >= 0: + sys.__stdout__.flush() # write hook output to stderr fd os.dup2(oldstdout, stdoutno) os.close(oldstdout) diff --git a/tests/test-ssh.t b/tests/test-ssh.t --- a/tests/test-ssh.t +++ b/tests/test-ssh.t @@ -265,8 +265,17 @@ a bad, evil hook that prints to stdout > sys.stdout.write("KABOOM\n") > EOF - $ echo '[hooks]' >> ../remote/.hg/hgrc - $ echo "changegroup.stdout = python $TESTTMP/badhook" >> ../remote/.hg/hgrc + $ cat < $TESTTMP/badpyhook.py + > import sys + > def hook(ui, repo, hooktype, **kwargs): + > sys.stdout.write("KABOOM IN PROCESS\n") + > EOF + + $ cat <> ../remote/.hg/hgrc + > [hooks] + > changegroup.stdout = python $TESTTMP/badhook + > changegroup.pystdout = python:$TESTTMP/badpyhook.py:hook + > EOF $ echo r > r $ hg ci -A -m z r @@ -281,6 +290,7 @@ push should succeed even though it has a remote: adding file changes remote: added 1 changesets with 1 changes to 1 files remote: KABOOM + remote: KABOOM IN PROCESS $ hg -R ../remote heads changeset: 5:1383141674ec tag: tip @@ -447,6 +457,7 @@ stderr from remote commands should be pr remote: adding file changes remote: added 1 changesets with 1 changes to 1 files remote: KABOOM + remote: KABOOM IN PROCESS local stdout debug output