BaseReceivePack: More validation during parseCommand

Change-Id: I25f3a5582a45dd0ec8f78f5daf74c2203797a184
This commit is contained in:
Dave Borowitz 2015-06-29 16:00:53 -07:00
parent 91e17b0080
commit 59b000a672
4 changed files with 65 additions and 25 deletions

View File

@ -13,17 +13,17 @@
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 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.
* 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.
* 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,
@ -43,7 +43,9 @@
package org.eclipse.jgit.transport;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.eclipse.jgit.errors.PackProtocolException;
import org.eclipse.jgit.lib.ObjectId;
import org.junit.Test;
@ -57,14 +59,34 @@ public void chomp() {
}
@Test
public void parseCommand() {
String input = "0000000000000000000000000000000000000000"
+ " deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
+ " refs/heads/master";
ReceiveCommand cmd = BaseReceivePack.parseCommand(input);
public void parseCommand() throws Exception {
String o = "0000000000000000000000000000000000000000";
String n = "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef";
String r = "refs/heads/master";
ReceiveCommand cmd = BaseReceivePack.parseCommand(o + " " + n + " " + r);
assertEquals(ObjectId.zeroId(), cmd.getOldId());
assertEquals("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
cmd.getNewId().name());
assertEquals("refs/heads/master", cmd.getRefName());
assertParseCommandFails(null);
assertParseCommandFails("");
assertParseCommandFails(o.substring(35) + " " + n.substring(35)
+ " " + r + "\n");
assertParseCommandFails(o + " " + n + " " + r + "\n");
assertParseCommandFails(o + " " + n + " " + "refs^foo");
assertParseCommandFails(o + " " + n.substring(10) + " " + r);
assertParseCommandFails(o.substring(10) + " " + n + " " + r);
assertParseCommandFails("X" + o.substring(1) + " " + n + " " + r);
assertParseCommandFails(o + " " + "X" + n.substring(1) + " " + r);
}
private void assertParseCommandFails(String input) {
try {
BaseReceivePack.parseCommand(input);
fail();
} catch (PackProtocolException e) {
// Expected.
}
}
}

View File

@ -114,10 +114,10 @@ public void noCert() throws Exception {
ObjectId oldId = ObjectId.zeroId();
ObjectId newId =
ObjectId.fromString("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef");
String rawLine =
oldId.name() + " " + newId.name() + " refs/heads/master";
ReceiveCommand cmd = BaseReceivePack.parseCommand(rawLine);
String line = oldId.name() + " " + newId.name() + " refs/heads/master";
String rawLine = line + "\n";
ReceiveCommand cmd = BaseReceivePack.parseCommand(line);
parser.addCommand(cmd, rawLine);
parser.addCommand(rawLine);
assertNull(parser.build());

View File

@ -1100,13 +1100,13 @@ protected void recvCommands() throws IOException {
continue;
}
if (line.length() < 83) {
final String m = JGitText.get().errorInvalidProtocolWantedOldNewRef;
sendError(m);
throw new PackProtocolException(m);
ReceiveCommand cmd;
try {
cmd = parseCommand(line);
} catch (PackProtocolException e) {
sendError(e.getMessage());
throw e;
}
final ReceiveCommand cmd = parseCommand(line);
if (cmd.getRefName().equals(Constants.HEAD)) {
cmd.setResult(Result.REJECTED_CURRENT_BRANCH);
} else {
@ -1129,10 +1129,26 @@ static String chomp(String line) {
return line;
}
static ReceiveCommand parseCommand(String line) {
ObjectId oldId = ObjectId.fromString(line.substring(0, 40));
ObjectId newId = ObjectId.fromString(line.substring(41, 81));
static ReceiveCommand parseCommand(String line) throws PackProtocolException {
if (line == null || line.length() < 83) {
throw new PackProtocolException(
JGitText.get().errorInvalidProtocolWantedOldNewRef);
}
String oldStr = line.substring(0, 40);
String newStr = line.substring(41, 81);
ObjectId oldId, newId;
try {
oldId = ObjectId.fromString(oldStr);
newId = ObjectId.fromString(newStr);
} catch (IllegalArgumentException e) {
throw new PackProtocolException(
JGitText.get().errorInvalidProtocolWantedOldNewRef, e);
}
String name = line.substring(82);
if (!Repository.isValidRefName(name)) {
throw new PackProtocolException(
JGitText.get().errorInvalidProtocolWantedOldNewRef);
}
return new ReceiveCommand(oldId, newId, name);
}

View File

@ -294,9 +294,11 @@ public void addCommand(ReceiveCommand cmd, String rawLine) {
* @param rawLine
* the exact line read from the wire that produced this
* command, including trailing newline if present.
* @throws PackProtocolException
* if the raw line cannot be parsed to a command.
* @since 4.0
*/
public void addCommand(String rawLine) {
public void addCommand(String rawLine) throws PackProtocolException {
commands.add(parseCommand(chomp(rawLine)));
rawCommands.append(rawLine);
}