From fcafdcc4048dbd61754b3f1d3ae19395fb788d45 Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Tue, 18 Dec 2018 21:00:42 -0800 Subject: [PATCH] UploadPack: Filter refs used for want-ref resolution In the longer term, we can add support for this to the RequestValidator interface. In the short term, this is a minimal band-aid to ensure any refs the client requests are visible to the client. Change-Id: I0683c7a00e707cf97eef6c6bb782671d0a550ffe Reported-by: Ivan Frade Signed-off-by: Jonathan Nieder Signed-off-by: Matthias Sohn --- .../jgit/transport/TransferConfig.java | 10 ++++++ .../eclipse/jgit/transport/UploadPack.java | 33 ++++++++++++++++++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java index 59740c4dc..db9539604 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java @@ -326,6 +326,16 @@ public class TransferConfig { }; } + /** + * Like {@code getRefFilter() == RefFilter.DEFAULT}, but faster. + * + * @return {@code true} if no ref filtering is needed because there + * are no configured hidden refs. + */ + boolean hasDefaultRefFilter() { + return hideRefs.length == 0; + } + static class FsckKeyNameHolder { private static final Map errors; 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 7e29c9b7a..bac877a27 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java @@ -847,6 +847,37 @@ public class UploadPack { .collect(toMap(Ref::getName, identity())); } + /** + * Read a ref 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 + * the unabbreviated name of the reference. + * @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 getRef(String name) throws IOException { + if (refs != null) { + return refs.get(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().exactRef(name); + } + return getAdvertisedOrDefaultRefs().get(name); + } + private void service() throws IOException { boolean sendPack = false; // If it's a non-bidi request, we need to read the entire request before @@ -1012,7 +1043,7 @@ public class UploadPack { wantIds.addAll(req.getWantsIds()); Map wantedRefs = new TreeMap<>(); for (String refName : req.getWantedRefs()) { - Ref ref = db.getRefDatabase().exactRef(refName); + Ref ref = getRef(refName); if (ref == null) { throw new PackProtocolException(MessageFormat .format(JGitText.get().invalidRefName, refName));