From eb4c63fbbf0972d64af09ba31fdd758944a677cb Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Sat, 22 Dec 2018 13:53:10 -0800 Subject: [PATCH] UploadPack: Filter refs used for deepen-not resolution Clients can use --shallow-exclude to obtain information about what commits are reachable from refs they are not supposed to be able to see. Plug the hole by allowing the AdvertiseRefsHook and RefFilter to take effect here, too. Change-Id: If2b8e95344fa49e10a6a202144318b60d002490e Signed-off-by: Jonathan Nieder --- .../eclipse/jgit/transport/UploadPack.java | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) 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 62e8ae0cc..2fbcaa292 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -98,6 +98,7 @@ import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectReader; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.RefDatabase; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.AsyncRevObjectQueue; import org.eclipse.jgit.revwalk.BitmapWalker; @@ -878,6 +879,38 @@ public class UploadPack { return getAdvertisedOrDefaultRefs().get(name); } + /** + * Find a ref in the usual search path on behalf of the client. + *

+ * This checks that the ref is present in the ref advertisement since + * otherwise the client might not be supposed to be able to read it. + * + * @param name + * short name of the ref to find, e.g. "master" to find + * "refs/heads/master". + * @return the requested Ref, or {@code null} if it is not visible or + * does not exist. + * @throws java.io.IOException + * on failure to read the ref or check it for visibility. + */ + @Nullable + private Ref findRef(String name) throws IOException { + if (refs != null) { + return RefDatabase.findRef(refs, name); + } + if (!advertiseRefsHookCalled) { + advertiseRefsHook.advertiseRefs(this); + advertiseRefsHookCalled = true; + } + if (refs == null && + refFilter == RefFilter.DEFAULT && + transferConfig.hasDefaultRefFilter()) { + // Fast path: no ref filtering is needed. + return db.getRefDatabase().getRef(name); + } + return RefDatabase.findRef(getAdvertisedOrDefaultRefs(), name); + } + private void service() throws IOException { boolean sendPack = false; // If it's a non-bidi request, we need to read the entire request before @@ -1033,7 +1066,7 @@ public class UploadPack { // copying data back to class fields List deepenNots = new ArrayList<>(); for (String s : req.getDeepenNotRefs()) { - Ref ref = db.getRefDatabase().getRef(s); + Ref ref = findRef(s); if (ref == null) { throw new PackProtocolException(MessageFormat .format(JGitText.get().invalidRefName, s));