Browse Source

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>
stable-5.1
Jonathan Nieder 6 years ago committed by Matthias Sohn
parent
commit
fcafdcc404
  1. 10
      org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java
  2. 33
      org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

10
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 { static class FsckKeyNameHolder {
private static final Map<String, ObjectChecker.ErrorType> errors; private static final Map<String, ObjectChecker.ErrorType> errors;

33
org.eclipse.jgit/src/org/eclipse/jgit/transport/UploadPack.java

@ -847,6 +847,37 @@ public class UploadPack {
.collect(toMap(Ref::getName, identity())); .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 { private void service() throws IOException {
boolean sendPack = false; boolean sendPack = false;
// If it's a non-bidi request, we need to read the entire request before // 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()); wantIds.addAll(req.getWantsIds());
Map<String, ObjectId> wantedRefs = new TreeMap<>(); Map<String, ObjectId> wantedRefs = new TreeMap<>();
for (String refName : req.getWantedRefs()) { for (String refName : req.getWantedRefs()) {
Ref ref = db.getRefDatabase().exactRef(refName); Ref ref = getRef(refName);
if (ref == null) { if (ref == null) {
throw new PackProtocolException(MessageFormat throw new PackProtocolException(MessageFormat
.format(JGitText.get().invalidRefName, refName)); .format(JGitText.get().invalidRefName, refName));

Loading…
Cancel
Save