@ -184,7 +184,7 @@ public class ReceivePack {
/** Lock around the received pack file, while updating refs. */
private PackLock packLock ;
private boolean ensureObjectsProvidedVisi ble;
private boolean checkReferencedIsReacha ble;
/ * *
* Create a new pack receive for an open repository .
@ -252,23 +252,36 @@ public class ReceivePack {
}
/ * *
* Configure this receive pack instance to ensure that the provided
* objects are visible to the user .
* @return true if this instance will validate all referenced , but not
* supplied by the client , objects are reachable from another
* reference .
* /
public boolean isCheckReferencedObjectsAreReachable ( ) {
return checkReferencedIsReachable ;
}
/ * *
* Validate all referenced but not supplied objects are reachable .
* < p >
* By default , a receive pack assumes that its user will only provide
* references to objects that it can see . Setting this flag to { @code true }
* will add an additional check that verifies that the objects that were
* provided are reachable by a tree or a commit that the user can see .
* If enabled , this instance will verify that references to objects not
* contained within the received pack are already reachable through at least
* one other reference selected by the { @link # getRefFilter ( ) } and displayed
* as part of { @link # getAdvertisedRefs ( ) } .
* < p >
* This option is useful when the code doesn ' t trust the client not to
* provide a forged SHA - 1 reference to an object in an attempt to access
* parts of the DAG that they aren ' t allowed to see , via the configured
* { @link RefFilter } .
* This feature is useful when the application doesn ' t trust the client to
* not provide a forged SHA - 1 reference to an object , in an attempt to
* access parts of the DAG that they aren ' t allowed to see and which have
* been hidden from them via the configured { @link RefFilter } .
* < p >
* Enabling this feature may imply at least some , if not all , of the same
* functionality performed by { @link # setCheckReceivedObjects ( boolean ) } .
* Applications are encouraged to enable both features , if desired .
*
* @param b { @code true } to enable the additional check .
* @param b
* { @code true } to enable the additional check .
* /
public void setEnsureProvidedObjectsVisible ( boolean b ) {
this . ensureObjectsProvidedVisi ble = b ;
public void setCheckReferencedObjectsAreReacha ble ( boolean b ) {
this . checkReferencedIsReacha ble = b ;
}
/ * *
@ -611,7 +624,7 @@ public class ReceivePack {
if ( needPack ( ) ) {
try {
receivePack ( ) ;
if ( isCheckReceivedObjects ( ) )
if ( needCheckConnectivity ( ) )
checkConnectivity ( ) ;
ip = null ;
unpackError = null ;
@ -761,8 +774,8 @@ public class ReceivePack {
ip = IndexPack . create ( db , rawIn ) ;
ip . setFixThin ( true ) ;
ip . setNeedNewObjectIds ( ensureObjectsProvidedVisi ble) ;
ip . setNeedBaseObjectIds ( ensureObjectsProvidedVisi ble) ;
ip . setNeedNewObjectIds ( checkReferencedIsReacha ble) ;
ip . setNeedBaseObjectIds ( checkReferencedIsReacha ble) ;
ip . setObjectChecking ( isCheckReceivedObjects ( ) ) ;
ip . index ( NullProgressMonitor . INSTANCE ) ;
@ -775,11 +788,16 @@ public class ReceivePack {
timeoutIn . setTimeout ( timeout * 1000 ) ;
}
private boolean needCheckConnectivity ( ) {
return isCheckReceivedObjects ( )
| | isCheckReferencedObjectsAreReachable ( ) ;
}
private void checkConnectivity ( ) throws IOException {
ObjectIdSubclassMap < ObjectId > baseObjects = null ;
ObjectIdSubclassMap < ObjectId > providedObjects = null ;
if ( ensureObjectsProvidedVisible ) {
if ( checkReferencedIsReacha ble) {
baseObjects = ip . getBaseObjectIds ( ) ;
providedObjects = ip . getNewObjectIds ( ) ;
}
@ -797,7 +815,7 @@ public class ReceivePack {
RevObject o = ow . parseAny ( ref . getObjectId ( ) ) ;
ow . markUninteresting ( o ) ;
if ( ensureObjectsProvidedVisi ble & & ! baseObjects . isEmpty ( ) ) {
if ( checkReferencedIsReacha ble & & ! baseObjects . isEmpty ( ) ) {
while ( o instanceof RevTag )
o = ( ( RevTag ) o ) . getObject ( ) ;
if ( o instanceof RevCommit )
@ -807,7 +825,7 @@ public class ReceivePack {
}
}
if ( ensureObjectsProvidedVisi ble) {
if ( checkReferencedIsReacha ble) {
for ( ObjectId id : baseObjects ) {
RevObject b = ow . lookupAny ( id , Constants . OBJ_BLOB ) ;
if ( ! b . has ( RevFlag . UNINTERESTING ) )
@ -817,13 +835,13 @@ public class ReceivePack {
RevCommit c ;
while ( ( c = ow . next ( ) ) ! = null ) {
if ( ensureObjectsProvidedVisi ble & & ! providedObjects . contains ( c ) )
if ( checkReferencedIsReacha ble & & ! providedObjects . contains ( c ) )
throw new MissingObjectException ( c , Constants . TYPE_COMMIT ) ;
}
RevObject o ;
while ( ( o = ow . nextObject ( ) ) ! = null ) {
if ( ensureObjectsProvidedVisi ble) {
if ( checkReferencedIsReacha ble) {
if ( providedObjects . contains ( o ) )
continue ;
else