summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJonathan Nieder <jrn@google.com>2018-12-18 21:00:42 -0800
committerMatthias Sohn <matthias.sohn@sap.com>2018-12-26 00:40:00 +0100
commitfcafdcc4048dbd61754b3f1d3ae19395fb788d45 (patch)
tree1c90c84949a017e2ff4e0eaaf38bce60c45e0c39
parent1638a2fce8e2a71f4cdfdee278e0cb9699860add (diff)
downloadjgit-fcafdcc4048dbd61754b3f1d3ae19395fb788d45.tar.gz
jgit-fcafdcc4048dbd61754b3f1d3ae19395fb788d45.zip
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 <ifrade@google.com> Signed-off-by: Jonathan Nieder <jrn@google.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java10
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java33
2 files changed, 42 insertions, 1 deletions
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 59740c4dc8..db95396047 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<String, ObjectChecker.ErrorType> 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 7e29c9b7a2..bac877a272 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.
+ * <p>
+ * 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<String, ObjectId> 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));