UploadPack: Verify clients send only commits for shallow lines
If a client mistakenly tries to send a tag object as a shallow line JGit blindly assumes this is a commit and tries to parse the tag buffer using the commit parser. This can cause an obtuse error like: InvalidObjectIdException: Invalid id: t c0ff331234... The "t" comes from the "object c0ff331234..." line of the tag tring to be parsed as though it where the "tree" line of a commit. Run any client supplied shallow lines through the RevWalk to lookup the object types. Fail fast with a protocol exception if any of them are non-commit. Skip objects not known to this repository. This matches behavior with git-core's upload-pack, which sliently skips over any shallow line object named by the client but not known by the server. Change-Id: Ic6c57a90a42813164ce65c2244705fc42e84d700
This commit is contained in:
parent
db0adc1e8c
commit
b46c446395
|
@ -344,6 +344,7 @@ invalidPathReservedOnWindows=Invalid path (''{0}'' is reserved on Windows): {1}
|
||||||
invalidReflogRevision=Invalid reflog revision: {0}
|
invalidReflogRevision=Invalid reflog revision: {0}
|
||||||
invalidRefName=Invalid ref name: {0}
|
invalidRefName=Invalid ref name: {0}
|
||||||
invalidRemote=Invalid remote: {0}
|
invalidRemote=Invalid remote: {0}
|
||||||
|
invalidShallowObject=invalid shallow object {0}, expected commit
|
||||||
invalidStageForPath=Invalid stage {0} for path {1}
|
invalidStageForPath=Invalid stage {0} for path {1}
|
||||||
invalidTagOption=Invalid tag option: {0}
|
invalidTagOption=Invalid tag option: {0}
|
||||||
invalidTimeout=Invalid timeout: {0}
|
invalidTimeout=Invalid timeout: {0}
|
||||||
|
|
|
@ -403,6 +403,7 @@ public static JGitText get() {
|
||||||
/***/ public String invalidReflogRevision;
|
/***/ public String invalidReflogRevision;
|
||||||
/***/ public String invalidRefName;
|
/***/ public String invalidRefName;
|
||||||
/***/ public String invalidRemote;
|
/***/ public String invalidRemote;
|
||||||
|
/***/ public String invalidShallowObject;
|
||||||
/***/ public String invalidStageForPath;
|
/***/ public String invalidStageForPath;
|
||||||
/***/ public String invalidTagOption;
|
/***/ public String invalidTagOption;
|
||||||
/***/ public String invalidTimeout;
|
/***/ public String invalidTimeout;
|
||||||
|
|
|
@ -1406,6 +1406,8 @@ void carryFlagsImpl(final RevCommit c) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assume additional commits are shallow (have no parents).
|
* Assume additional commits are shallow (have no parents).
|
||||||
|
* <p>
|
||||||
|
* This method is a No-op if the collection is empty.
|
||||||
*
|
*
|
||||||
* @param ids
|
* @param ids
|
||||||
* commits that should be treated as shallow commits, in addition
|
* commits that should be treated as shallow commits, in addition
|
||||||
|
|
|
@ -735,6 +735,8 @@ else if (requestValidator instanceof AnyRequestValidator)
|
||||||
else
|
else
|
||||||
multiAck = MultiAck.OFF;
|
multiAck = MultiAck.OFF;
|
||||||
|
|
||||||
|
if (!clientShallowCommits.isEmpty())
|
||||||
|
verifyClientShallow();
|
||||||
if (depth != 0)
|
if (depth != 0)
|
||||||
processShallow();
|
processShallow();
|
||||||
if (!clientShallowCommits.isEmpty())
|
if (!clientShallowCommits.isEmpty())
|
||||||
|
@ -820,6 +822,35 @@ private void processShallow() throws IOException {
|
||||||
pckOut.end();
|
pckOut.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void verifyClientShallow()
|
||||||
|
throws IOException, PackProtocolException {
|
||||||
|
AsyncRevObjectQueue q = walk.parseAny(clientShallowCommits, true);
|
||||||
|
try {
|
||||||
|
for (;;) {
|
||||||
|
try {
|
||||||
|
// Shallow objects named by the client must be commits.
|
||||||
|
RevObject o = q.next();
|
||||||
|
if (o == null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!(o instanceof RevCommit)) {
|
||||||
|
throw new PackProtocolException(
|
||||||
|
MessageFormat.format(
|
||||||
|
JGitText.get().invalidShallowObject,
|
||||||
|
o.name()));
|
||||||
|
}
|
||||||
|
} catch (MissingObjectException notCommit) {
|
||||||
|
// shallow objects not known at the server are ignored
|
||||||
|
// by git-core upload-pack, match that behavior.
|
||||||
|
clientShallowCommits.remove(notCommit.getObjectId());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
q.release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate an advertisement of available refs and capabilities.
|
* Generate an advertisement of available refs and capabilities.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue