From f960bbd0b9110534c8ce50bef210f528ac304e06 Mon Sep 17 00:00:00 2001 From: Rene Pfeuffer Date: Mon, 18 Nov 2019 12:51:16 +0100 Subject: [PATCH] Replace quotes in git command line, too --- .../scm/repository/spi/GitDiffCommand.java | 130 ++++++++++++------ ...itDiffCommand_DequoteOutputStreamTest.java | 4 +- 2 files changed, 87 insertions(+), 47 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitDiffCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitDiffCommand.java index c165ee550e..d6203f2a1b 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitDiffCommand.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitDiffCommand.java @@ -45,7 +45,6 @@ import java.io.OutputStream; import static java.nio.charset.StandardCharsets.UTF_8; /** - * * @author Sebastian Sdorra */ public class GitDiffCommand extends AbstractGitCommand implements DiffCommand { @@ -57,7 +56,7 @@ public class GitDiffCommand extends AbstractGitCommand implements DiffCommand { @Override public DiffCommandBuilder.OutputStreamConsumer getDiffResult(DiffCommandRequest request) throws IOException { @SuppressWarnings("squid:S2095") // repository will be closed with the RepositoryService - org.eclipse.jgit.lib.Repository repository = open(); + org.eclipse.jgit.lib.Repository repository = open(); Differ.Diff diff = Differ.diff(repository, request); @@ -78,12 +77,19 @@ public class GitDiffCommand extends AbstractGitCommand implements DiffCommand { static class DequoteOutputStream extends OutputStream { + private static final String[] DEQUOTE_STARTS = { + "--- ", + "+++ ", + "diff --git " + }; + private final OutputStream target; - private boolean afterNL = false; + private boolean afterNL = true; private boolean writeToBuffer = false; - private int minusCount = 0; - private int plusCount = 0; + private int numberOfPotentialBeginning = -1; + private int potentialBeginningCharCount = 0; + private boolean inPotentialQuotedLine = false; private final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); @@ -93,54 +99,88 @@ public class GitDiffCommand extends AbstractGitCommand implements DiffCommand { @Override public void write(int i) throws IOException { - if (i == (int) '+' && afterNL) { - plusCount = 1; + if (i == (int) '\n') { + handleNewLine(i); + return; + } + + if (afterNL) { afterNL = false; - target.write(i); - } else if (i == (int) '+' && plusCount > 0) { - ++plusCount; - afterNL = false; - target.write(i); - } else if (i == (int) '-' && afterNL) { - minusCount = 1; - afterNL = false; - target.write(i); - } else if (i == (int) '-' && minusCount > 0) { - ++minusCount; - afterNL = false; - target.write(i); - } else if (i == (int) ' ' && plusCount == 3) { - writeToBuffer = true; - buffer.reset(); - afterNL = false; - plusCount = 0; - target.write(i); - } else if (i == (int) ' ' && minusCount == 3) { - minusCount = 0; - afterNL = false; - writeToBuffer = true; - buffer.reset(); - target.write(i); - } else if (i == (int) '\n') { - afterNL = true; - if (writeToBuffer) { - byte[] bytes = buffer.toByteArray(); - String dequote = QuotedString.GIT_PATH.dequote(bytes, 0, bytes.length); - target.write(dequote.getBytes(UTF_8)); - writeToBuffer = false; + if (foundPotentialBeginning(i)) { + return; } - target.write(i); - } else if (writeToBuffer) { + numberOfPotentialBeginning = -1; + } + + if (inPotentialQuotedLine && i == '"') { + handleQuote(); + return; + } + + if (numberOfPotentialBeginning > -1 && checkForFurtherBeginning(i)) { + return; + } + + if (writeToBuffer) { buffer.write(i); - afterNL = false; } else { target.write(i); - afterNL = false; - minusCount = 0; - plusCount = 0; } } + private boolean checkForFurtherBeginning(int i) throws IOException { + if (i == DEQUOTE_STARTS[numberOfPotentialBeginning].charAt(potentialBeginningCharCount)) { + if (potentialBeginningCharCount + 1 < DEQUOTE_STARTS[numberOfPotentialBeginning].length()) { + ++potentialBeginningCharCount; + } else { + inPotentialQuotedLine = true; + } + target.write(i); + return true; + } else { + numberOfPotentialBeginning = -1; + } + return false; + } + + private boolean foundPotentialBeginning(int i) throws IOException { + for (int n = 0; n < DEQUOTE_STARTS.length; ++n) { + if (i == DEQUOTE_STARTS[n].charAt(0)) { + numberOfPotentialBeginning = n; + potentialBeginningCharCount = 1; + target.write(i); + return true; + } + } + return false; + } + + private void handleQuote() throws IOException { + if (writeToBuffer) { + buffer.write('"'); + dequoteBuffer(); + } else { + writeToBuffer = true; + buffer.reset(); + buffer.write('"'); + } + } + + private void handleNewLine(int i) throws IOException { + afterNL = true; + if (writeToBuffer) { + dequoteBuffer(); + } + target.write(i); + } + + private void dequoteBuffer() throws IOException { + byte[] bytes = buffer.toByteArray(); + String dequote = QuotedString.GIT_PATH.dequote(bytes, 0, bytes.length); + target.write(dequote.getBytes(UTF_8)); + writeToBuffer = false; + } + @Override public void flush() throws IOException { target.flush(); diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitDiffCommand_DequoteOutputStreamTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitDiffCommand_DequoteOutputStreamTest.java index 790bb34b4e..8eaab4fc16 100644 --- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitDiffCommand_DequoteOutputStreamTest.java +++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitDiffCommand_DequoteOutputStreamTest.java @@ -10,7 +10,7 @@ public class GitDiffCommand_DequoteOutputStreamTest { @Test void shouldDequoteText() throws IOException { - String s = "diff --git \"a/\\303\\272\\303\\274\\303\\276\\303\\253\\303\\251\\303\\245\\303\\253\\303\\245\\303\\251 \\303\\245g\\303\\260f\\303\\237\" \"b/\\303\\272\\303\\274\\303\\276\\303\\253\\303\\251\\303\\245\\303\\253\\303\\245\\303\\251 \\303\\245g\\303\\260f\\303\\237\"\n" + + String s = "diff --git \"a/file \\303\\272\\303\\274\\303\\276\\303\\253\\303\\251\\303\\245\\303\\253\\303\\245\\303\\251 a\" \"b/file \\303\\272\\303\\274\\303\\276\\303\\253\\303\\251\\303\\245\\303\\253\\303\\245\\303\\251 b\"\n" + "new file mode 100644\n" + "index 0000000..8cb0607\n" + "--- /dev/null\n" + @@ -24,7 +24,7 @@ public class GitDiffCommand_DequoteOutputStreamTest { stream.write(bytes, 0, bytes.length); stream.flush(); - Assertions.assertThat(buffer.toString()).isEqualTo("diff --git \"a/\\303\\272\\303\\274\\303\\276\\303\\253\\303\\251\\303\\245\\303\\253\\303\\245\\303\\251 \\303\\245g\\303\\260f\\303\\237\" \"b/\\303\\272\\303\\274\\303\\276\\303\\253\\303\\251\\303\\245\\303\\253\\303\\245\\303\\251 \\303\\245g\\303\\260f\\303\\237\"\n" + + Assertions.assertThat(buffer.toString()).isEqualTo("diff --git a/file úüþëéåëåé a b/file úüþëéåëåé b\n" + "new file mode 100644\n" + "index 0000000..8cb0607\n" + "--- /dev/null\n" +