From 644060b7a4bc98384b66e3d2343b950b875b5e35 Mon Sep 17 00:00:00 2001 From: pcloudy Date: Thu, 22 Aug 2019 03:21:13 -0700 Subject: [PATCH] Fix PatchUtil for parsing special patch format `diff` generate incomplete header for adding or removing one line file. Eg. """ --- foo +++ bar @@ -1 +0,0 @@ # Should be @@ -1,1 +0,0 @@ -hello, world """ We set the default value to 1 when the size info is missing. Similar logic in `git apply` implementation: https://github.com/git/git/blob/5fa0f5238b0cd46cfe7f6fa76c3f526ea98148d9/apply.c#L1400 Fixes https://github.com/bazelbuild/bazel/issues/9222 RELNOTES: None PiperOrigin-RevId: 264799477 --- .../build/lib/bazel/repository/PatchUtil.java | 7 ++-- .../lib/bazel/repository/PatchUtilTest.java | 32 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/PatchUtil.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/PatchUtil.java index cd3a4f5dea0b14..8c0a2da84a7715 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/repository/PatchUtil.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/PatchUtil.java @@ -64,8 +64,11 @@ public Result check(int oldLineCnt, int newLineCnt) { ChunkHeader(String header) throws PatchFailedException { Matcher m = CHUNK_HEADER_RE.matcher(header); if (m.find()) { - oldSize = Integer.parseInt(m.group(2)); - newSize = Integer.parseInt(m.group(4)); + String size; + size = m.group(2); + oldSize = (size == null) ? 1 : Integer.parseInt(size); + size = m.group(4); + newSize = (size == null) ? 1 : Integer.parseInt(size); } else { throw new PatchFailedException("Wrong chunk header: " + header); } diff --git a/src/test/java/com/google/devtools/build/lib/bazel/repository/PatchUtilTest.java b/src/test/java/com/google/devtools/build/lib/bazel/repository/PatchUtilTest.java index dd00c570a0d489..5fbcace554a2b1 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/repository/PatchUtilTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/repository/PatchUtilTest.java @@ -65,6 +65,24 @@ public void testAddFile() throws IOException, PatchFailedException { assertThat(PatchUtil.readFile(newFile)).containsExactlyElementsIn(newFileContent); } + @Test + public void testAddOneLineFile() throws IOException, PatchFailedException { + Path patchFile = + scratch.file( + "/root/patchfile", + "diff --git a/newfile b/newfile", + "new file mode 100644", + "index 0000000..f742c88", + "--- /dev/null", + "+++ b/newfile", + "@@ -0,0 +1 @@", // diff will produce such chunk header for one line file. + "+hello, world"); + PatchUtil.apply(patchFile, 1, root); + Path newFile = root.getRelative("newfile"); + ImmutableList newFileContent = ImmutableList.of("hello, world"); + assertThat(PatchUtil.readFile(newFile)).containsExactlyElementsIn(newFileContent); + } + @Test public void testDeleteFile() throws IOException, PatchFailedException { Path oldFile = scratch.file("/root/oldfile", "I'm an old file", "bye, world"); @@ -80,6 +98,20 @@ public void testDeleteFile() throws IOException, PatchFailedException { assertThat(oldFile.exists()).isFalse(); } + @Test + public void testDeleteOneLineFile() throws IOException, PatchFailedException { + Path oldFile = scratch.file("/root/oldfile", "bye, world"); + Path patchFile = + scratch.file( + "/root/patchfile", + "--- a/oldfile", + "+++ /dev/null", + "@@ -1 +0,0 @@", // diff will produce such chunk header for one line file. + "-bye, world"); + PatchUtil.apply(patchFile, 1, root); + assertThat(oldFile.exists()).isFalse(); + } + @Test public void testDeleteAllContentButNotFile() throws IOException, PatchFailedException { // If newfile is not /dev/null, we don't delete the file even it's empty after patching,