From 485b751b2fb74b5ea11582787d859c6cd59b65d2 Mon Sep 17 00:00:00 2001 From: Shawn Pearce Date: Mon, 24 Nov 2014 14:51:09 -0800 Subject: [PATCH] Allow configurable ObjectCheckers in fetch RecievePack already honors fsck settings for safeForWindows and safeForMacOS. Allow those same checks to be performed during fetch through a caller-configurable ObjectChecker. Default the fetch fsck options to match the current platform, as it can be reasonably assumed the repository will be accessed here. Change-Id: I3c0f411fad209c6bd8fb9c4acf5c55a6799a6a2a --- .../transport/BasePackFetchConnection.java | 2 +- .../jgit/transport/BundleFetchConnection.java | 2 +- .../jgit/transport/TransferConfig.java | 35 +++++++++++++++++-- .../org/eclipse/jgit/transport/Transport.java | 33 ++++++++++++++--- .../jgit/transport/WalkFetchConnection.java | 2 +- 5 files changed, 63 insertions(+), 11 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java index e7e8af50a..f907891ba 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackFetchConnection.java @@ -757,7 +757,7 @@ private void receivePack(final ProgressMonitor monitor, try { PackParser parser = ins.newPackParser(input); parser.setAllowThin(thinPack); - parser.setObjectChecking(transport.isCheckFetchedObjects()); + parser.setObjectChecker(transport.getObjectChecker()); parser.setLockMessage(lockMessage); packLock = parser.parse(monitor); ins.flush(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java index 15ff9d362..e3cfd22ad 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BundleFetchConnection.java @@ -187,7 +187,7 @@ protected void doFetch(final ProgressMonitor monitor, try { PackParser parser = ins.newPackParser(bin); parser.setAllowThin(true); - parser.setObjectChecking(transport.isCheckFetchedObjects()); + parser.setObjectChecker(transport.getObjectChecker()); parser.setLockMessage(lockMessage); packLock = parser.parse(NullProgressMonitor.INSTANCE); ins.flush(); 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 b00d607ee..1de91a57e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransferConfig.java @@ -48,8 +48,10 @@ import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Config.SectionParser; +import org.eclipse.jgit.lib.ObjectChecker; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.util.SystemReader; /** * The standard "transfer", "fetch", "receive", and "uploadpack" configuration @@ -63,7 +65,10 @@ public TransferConfig parse(final Config cfg) { } }; - private final boolean fetchFsck; + private final boolean checkReceivedObjects; + private final boolean allowLeadingZeroFileMode; + private final boolean safeForWindows; + private final boolean safeForMacOS; private final boolean allowTipSha1InWant; private final String[] hideRefs; @@ -72,9 +77,17 @@ public TransferConfig parse(final Config cfg) { } private TransferConfig(final Config rc) { - fetchFsck = rc.getBoolean( + checkReceivedObjects = rc.getBoolean( "fetch", "fsckobjects", //$NON-NLS-1$ //$NON-NLS-2$ rc.getBoolean("transfer", "fsckobjects", false)); //$NON-NLS-1$ //$NON-NLS-2$ + allowLeadingZeroFileMode = checkReceivedObjects + && rc.getBoolean("fsck", "allowLeadingZeroFileMode", false); //$NON-NLS-1$ //$NON-NLS-2$ + safeForWindows = checkReceivedObjects + && rc.getBoolean("fsck", "safeForWindows", //$NON-NLS-1$ //$NON-NLS-2$ + SystemReader.getInstance().isWindows()); + safeForMacOS = checkReceivedObjects + && rc.getBoolean("fsck", "safeForMacOS", //$NON-NLS-1$ //$NON-NLS-2$ + SystemReader.getInstance().isMacOS()); allowTipSha1InWant = rc.getBoolean( "uploadpack", "allowtipsha1inwant", false); //$NON-NLS-1$ //$NON-NLS-2$ @@ -83,9 +96,25 @@ private TransferConfig(final Config rc) { /** * @return strictly verify received objects? + * @deprecated use {@link #newObjectChecker()} instead. */ + @Deprecated public boolean isFsckObjects() { - return fetchFsck; + return checkReceivedObjects; + } + + /** + * @return checker to verify fetched objects, or null if checking is not + * enabled in the repository configuration. + * @since 3.6 + */ + public ObjectChecker newObjectChecker() { + if (!checkReceivedObjects) + return null; + return new ObjectChecker() + .setAllowLeadingZeroFileMode(allowLeadingZeroFileMode) + .setSafeForWindows(safeForWindows) + .setSafeForMacOS(safeForMacOS); } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java index 3ad1db2d4..218562254 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Transport.java @@ -75,6 +75,7 @@ import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.NullProgressMonitor; +import org.eclipse.jgit.lib.ObjectChecker; import org.eclipse.jgit.lib.ProgressMonitor; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; @@ -746,7 +747,7 @@ private static String findTrackingRefName(final String remoteName, private boolean dryRun; /** Should an incoming (fetch) transfer validate objects? */ - private boolean checkFetchedObjects; + private ObjectChecker objectChecker; /** Should refs no longer on the source be pruned from the destination? */ private boolean removeDeletedRefs; @@ -775,7 +776,7 @@ protected Transport(final Repository local, final URIish uri) { final TransferConfig tc = local.getConfig().get(TransferConfig.KEY); this.local = local; this.uri = uri; - this.checkFetchedObjects = tc.isFsckObjects(); + this.objectChecker = tc.newObjectChecker(); this.credentialsProvider = CredentialsProvider.getDefault(); } @@ -787,7 +788,7 @@ protected Transport(final Repository local, final URIish uri) { protected Transport(final URIish uri) { this.uri = uri; this.local = null; - this.checkFetchedObjects = true; + this.objectChecker = new ObjectChecker(); this.credentialsProvider = CredentialsProvider.getDefault(); } @@ -873,16 +874,38 @@ public void setFetchThin(final boolean fetchThin) { * client side of the connection. */ public boolean isCheckFetchedObjects() { - return checkFetchedObjects; + return getObjectChecker() != null; } /** * @param check * true to enable checking received objects; false to assume all * received objects are valid. + * @see #setObjectChecker(ObjectChecker) */ public void setCheckFetchedObjects(final boolean check) { - checkFetchedObjects = check; + if (check && objectChecker == null) + setObjectChecker(new ObjectChecker()); + else if (!check && objectChecker != null) + setObjectChecker(null); + } + + /** + * @return configured object checker for received objects, or null. + * @since 3.6 + */ + public ObjectChecker getObjectChecker() { + return objectChecker; + } + + /** + * @param impl + * if non-null the object checking instance to verify each + * received object with; null to disable object checking. + * @since 3.6 + */ + public void setObjectChecker(ObjectChecker impl) { + objectChecker = impl; } /** diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java index 565b457ac..6b7183b75 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkFetchConnection.java @@ -193,7 +193,7 @@ class WalkFetchConnection extends BaseFetchConnection { WalkFetchConnection(final WalkTransport t, final WalkRemoteObjectDatabase w) { Transport wt = (Transport)t; local = wt.local; - objCheck = wt.isCheckFetchedObjects() ? new ObjectChecker() : null; + objCheck = wt.getObjectChecker(); inserter = local.newObjectInserter(); reader = local.newObjectReader();