Allow trailing newlines in receive-pack
C git's receive-pack.c strips trailing newlines in command lists when present[1], although send-pack.c does not send them, at least in the case of command lists[2]. Change JGit to match this behavior. Add tests. This also fixes parsing of commands in the push cert, which, unlike commands sent in the non-push case, always have trailing newlines. [1]7974889a05/builtin/receive-pack.c (L1380)
where packet_read_line chomps newlines:7974889a05/pkt-line.c (L202)
[2]7974889a05/send-pack.c (L470)
Change-Id: I4bca6342a7482a53c9a5815a94b3c181a479d04b
This commit is contained in:
parent
2508f1695f
commit
d43703624c
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015, Google Inc.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available
|
||||||
|
* under the terms of the Eclipse Distribution License v1.0 which
|
||||||
|
* accompanies this distribution, is reproduced below, and is
|
||||||
|
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||||
|
*
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or
|
||||||
|
* without modification, are permitted provided that the following
|
||||||
|
* conditions are met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials provided
|
||||||
|
* with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of the Eclipse Foundation, Inc. nor the
|
||||||
|
* names of its contributors may be used to endorse or promote
|
||||||
|
* products derived from this software without specific prior
|
||||||
|
* written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||||
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.eclipse.jgit.transport;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/** Tests for base receive-pack utilities. */
|
||||||
|
public class BaseReceivePackTest {
|
||||||
|
@Test
|
||||||
|
public void chomp() {
|
||||||
|
assertEquals("foo", BaseReceivePack.chomp("foo"));
|
||||||
|
assertEquals("foo", BaseReceivePack.chomp("foo\n"));
|
||||||
|
assertEquals("foo\n", BaseReceivePack.chomp("foo\n\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void parseCommand() {
|
||||||
|
String input = "0000000000000000000000000000000000000000"
|
||||||
|
+ " deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
|
||||||
|
+ " refs/heads/master";
|
||||||
|
ReceiveCommand cmd = BaseReceivePack.parseCommand(input);
|
||||||
|
assertEquals(ObjectId.zeroId(), cmd.getOldId());
|
||||||
|
assertEquals("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
|
||||||
|
cmd.getNewId().name());
|
||||||
|
assertEquals("refs/heads/master", cmd.getRefName());
|
||||||
|
}
|
||||||
|
}
|
|
@ -1037,16 +1037,18 @@ public void sendAdvertisedRefs(final RefAdvertiser adv)
|
||||||
*/
|
*/
|
||||||
protected void recvCommands() throws IOException {
|
protected void recvCommands() throws IOException {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
String line;
|
String rawLine;
|
||||||
try {
|
try {
|
||||||
line = pckIn.readStringRaw();
|
rawLine = pckIn.readStringRaw();
|
||||||
} catch (EOFException eof) {
|
} catch (EOFException eof) {
|
||||||
if (commands.isEmpty())
|
if (commands.isEmpty())
|
||||||
return;
|
return;
|
||||||
throw eof;
|
throw eof;
|
||||||
}
|
}
|
||||||
if (line == PacketLineIn.END)
|
if (rawLine == PacketLineIn.END) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
String line = chomp(rawLine);
|
||||||
|
|
||||||
if (line.length() >= 48 && line.startsWith("shallow ")) { //$NON-NLS-1$
|
if (line.length() >= 48 && line.startsWith("shallow ")) { //$NON-NLS-1$
|
||||||
clientShallowCommits.add(ObjectId.fromString(line.substring(8, 48)));
|
clientShallowCommits.add(ObjectId.fromString(line.substring(8, 48)));
|
||||||
|
@ -1066,8 +1068,11 @@ protected void recvCommands() throws IOException {
|
||||||
if (line.equals("-----BEGIN PGP SIGNATURE-----\n")) //$NON-NLS-1$
|
if (line.equals("-----BEGIN PGP SIGNATURE-----\n")) //$NON-NLS-1$
|
||||||
pushCertificateParser.receiveSignature(pckIn);
|
pushCertificateParser.receiveSignature(pckIn);
|
||||||
|
|
||||||
if (pushCertificateParser.enabled())
|
if (pushCertificateParser.enabled()) {
|
||||||
pushCertificateParser.addCommand(line);
|
// Must use raw line with optional newline so signed payload can be
|
||||||
|
// reconstructed.
|
||||||
|
pushCertificateParser.addCommand(rawLine);
|
||||||
|
}
|
||||||
|
|
||||||
if (line.length() < 83) {
|
if (line.length() < 83) {
|
||||||
final String m = JGitText.get().errorInvalidProtocolWantedOldNewRef;
|
final String m = JGitText.get().errorInvalidProtocolWantedOldNewRef;
|
||||||
|
@ -1075,11 +1080,8 @@ protected void recvCommands() throws IOException {
|
||||||
throw new PackProtocolException(m);
|
throw new PackProtocolException(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
final ObjectId oldId = ObjectId.fromString(line.substring(0, 40));
|
final ReceiveCommand cmd = parseCommand(line);
|
||||||
final ObjectId newId = ObjectId.fromString(line.substring(41, 81));
|
if (cmd.getRefName().equals(Constants.HEAD)) {
|
||||||
final String name = line.substring(82);
|
|
||||||
final ReceiveCommand cmd = new ReceiveCommand(oldId, newId, name);
|
|
||||||
if (name.equals(Constants.HEAD)) {
|
|
||||||
cmd.setResult(Result.REJECTED_CURRENT_BRANCH);
|
cmd.setResult(Result.REJECTED_CURRENT_BRANCH);
|
||||||
} else {
|
} else {
|
||||||
cmd.setRef(refs.get(cmd.getRefName()));
|
cmd.setRef(refs.get(cmd.getRefName()));
|
||||||
|
@ -1088,6 +1090,21 @@ protected void recvCommands() throws IOException {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String chomp(String line) {
|
||||||
|
if (line != null && !line.isEmpty()
|
||||||
|
&& line.charAt(line.length() - 1) == '\n') {
|
||||||
|
return line.substring(0, line.length() - 1);
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ReceiveCommand parseCommand(String line) {
|
||||||
|
ObjectId oldId = ObjectId.fromString(line.substring(0, 40));
|
||||||
|
ObjectId newId = ObjectId.fromString(line.substring(41, 81));
|
||||||
|
String name = line.substring(82);
|
||||||
|
return new ReceiveCommand(oldId, newId, name);
|
||||||
|
}
|
||||||
|
|
||||||
/** Enable capabilities based on a previously read capabilities line. */
|
/** Enable capabilities based on a previously read capabilities line. */
|
||||||
protected void enableCapabilities() {
|
protected void enableCapabilities() {
|
||||||
sideBand = isCapabilityEnabled(CAPABILITY_SIDE_BAND_64K);
|
sideBand = isCapabilityEnabled(CAPABILITY_SIDE_BAND_64K);
|
||||||
|
|
Loading…
Reference in New Issue