]> granicus.if.org Git - git/commitdiff
fsmonitor: read entirety of watchman output
authorAlex Vandiver <alexmv@dropbox.com>
Wed, 4 Oct 2017 06:27:46 +0000 (23:27 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 4 Oct 2017 09:58:53 +0000 (18:58 +0900)
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>
t/t7519/fsmonitor-watchman
templates/hooks--fsmonitor-watchman.sample

index cca3d71e9073a655350e2522eb6075c0c46216ea..51330f8b3d73d513856747264342cefac32ba802 100755 (executable)
@@ -50,9 +50,6 @@ launch_watchman();
 
 sub launch_watchman {
 
-       # Set input record separator
-       local $/ = 0666;
-
        my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j')
            or die "open2() failed: $!\n" .
            "Falling back to scanning...\n";
@@ -83,7 +80,8 @@ sub launch_watchman {
        close $fh;
 
        print CHLD_IN $query;
-       my $response = <CHLD_OUT>;
+       close CHLD_IN;
+       my $response = do {local $/; <CHLD_OUT>};
 
        open ($fh, ">", ".git/watchman-response.json");
        print $fh $response;
index c68038ef0045f55bb5675f899d59b94f335d1284..9eba8a740933dfa77d7155aca2ba1979e9d0fb68 100755 (executable)
@@ -49,9 +49,6 @@ launch_watchman();
 
 sub launch_watchman {
 
-       # Set input record separator
-       local $/ = 0666;
-
        my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j')
            or die "open2() failed: $!\n" .
            "Falling back to scanning...\n";
@@ -78,7 +75,8 @@ sub launch_watchman {
        END
 
        print CHLD_IN $query;
-       my $response = <CHLD_OUT>;
+       close CHLD_IN;
+       my $response = do {local $/; <CHLD_OUT>};
 
        die "Watchman: command returned no output.\n" .
            "Falling back to scanning...\n" if $response eq "";