fsmonitor: read entirety of watchman output
In Perl, setting $/ sets the string that is used as the "record separator," which sets the boundary that the `<>` construct reads to. Setting `local $/ = 0666;` evaluates the octal, getting 438, and stringifies it. Thus, the later read from `<CHLD_OUT>` stops as soon as it encounters the string "438" in the watchman output, yielding invalid JSON; repositories containing filenames with SHA1 hashes are able to trip this easily. Set `$/` to undefined, thus slurping all output from watchman. Also close STDIN which is provided to watchman, to better guarantee that we cannot deadlock with watchman while both attempting to read. Signed-off-by: Alex Vandiver <alexmv@dropbox.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Alex Vandiver committed
Oct 3, 2017 at 23:27 UTC
2a387b17c5bc5e0872bed352a41a2b312ea86f9b
2 files changed
+4
-8
t/t7519/fsmonitor-watchman
+2
-4
@@ -50,9 +50,6 @@ launch_watchman();
50
51
sub launch_watchman {
52
53
- # Set input record separator
54
- local $/ = 0666;
55
-
53
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j')
54
or die "open2() failed: $!\n" .
55
"Falling back to scanning...\n";
@@ -83,7 +80,8 @@ sub launch_watchman {
80
close $fh;
81
82
print CHLD_IN $query;
86
- my $response = <CHLD_OUT>;
83
+ close CHLD_IN;
84
+ my $response = do {local $/; <CHLD_OUT>};
85
86
open ($fh, ">", ".git/watchman-response.json");
87
print $fh $response;
templates/hooks--fsmonitor-watchman.sample
+2
-4
@@ -49,9 +49,6 @@ launch_watchman();
49
50
sub launch_watchman {
51
52
- # Set input record separator
53
- local $/ = 0666;
54
-
52
my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j')
53
or die "open2() failed: $!\n" .
54
"Falling back to scanning...\n";
@@ -78,7 +75,8 @@ sub launch_watchman {
75
END
76
77
print CHLD_IN $query;
81
- my $response = <CHLD_OUT>;
78
+ close CHLD_IN;
79
+ my $response = do {local $/; <CHLD_OUT>};
80
81
die "Watchman: command returned no output.\n" .
82
"Falling back to scanning...\n" if $response eq "";