diff options
author | Shawn Pearce <spearce@spearce.org> | 2015-09-14 12:18:20 -0700 |
---|---|---|
committer | Shawn Pearce <spearce@spearce.org> | 2015-09-14 12:53:34 -0700 |
commit | b46c4463959f45b32e471e4c10b5ddc71232949e (patch) | |
tree | 035ba29440ca34bde7cfe111eb1798c63ef385d9 /org.eclipse.jgit/src/org/eclipse/jgit | |
parent | db0adc1e8cfeb19b2f25b6f1850c27865b570303 (diff) | |
download | jgit-b46c4463959f45b32e471e4c10b5ddc71232949e.tar.gz jgit-b46c4463959f45b32e471e4c10b5ddc71232949e.zip |
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
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit')
3 files changed, 34 insertions, 0 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java index c227884d58..d6cf6e6a7f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/JGitText.java @@ -403,6 +403,7 @@ public class JGitText extends TranslationBundle { /***/ public String invalidReflogRevision; /***/ public String invalidRefName; /***/ public String invalidRemote; + /***/ public String invalidShallowObject; /***/ public String invalidStageForPath; /***/ public String invalidTagOption; /***/ public String invalidTimeout; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java index afb208ecf9..1176d958b0 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/RevWalk.java @@ -1406,6 +1406,8 @@ public class RevWalk implements Iterable<RevCommit>, AutoCloseable { /** * Assume additional commits are shallow (have no parents). + * <p> + * This method is a No-op if the collection is empty. * * @param ids * commits that should be treated as shallow commits, in addition diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java index e0d900db8c..101057fb4f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -735,6 +735,8 @@ public class UploadPack { else multiAck = MultiAck.OFF; + if (!clientShallowCommits.isEmpty()) + verifyClientShallow(); if (depth != 0) processShallow(); if (!clientShallowCommits.isEmpty()) @@ -820,6 +822,35 @@ public class UploadPack { 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. * |