svnBridge Failure with IndexOutOfBounds

Jul 25, 2011 at 9:19 PM

hi,

I had svnBridge working against TFS 10.0.0 (from within Eclipse) using the svnBridge client (v6) for a few days then it suddenly started failing with IndexOutOfBounds exceptions (stack trace below).

This failure happens when simply browsing under a specific directory under a TFS project. Other directories under the project are fine. The one failing has the most children directories/files of the others so Im wondering if there is an inherent limit to the number that can be supported in svnBridge SVN Browse ?

System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at SvnBridge.SourceControl.TFSSourceControlProvider.GetLog(String path, Int32 itemVersion, Int32 versionFrom, Int32 versionTo, Recursion recursion, Int32 maxCount)
   at SvnBridge.SourceControl.TFSSourceControlProvider.UpdateFolderRevisions(ItemMetaData item, Int32 version, Recursion recursion)
   at SvnBridge.SourceControl.TFSSourceControlProvider.UpdateFolderRevisions(ItemMetaData item, Int32 version, Recursion recursion)
   at SvnBridge.SourceControl.TFSSourceControlProvider.GetItems(Int32 version, String path, Recursion recursion, Boolean returnPropertyFiles)
   at SvnBridge.SourceControl.TFSSourceControlProvider.GetItemsWithoutProperties(Int32 version, String path, Recursion recursion)
   at SvnBridge.Proxies.RemotingInvocation.Proceed()
   at SvnBridge.Proxies.TracingInterceptor.Invoke(IInvocation invocation)
   at SvnBridge.Proxies.RemotingInvocation.Proceed()
   at SvnBridge.Proxies.RetryOnExceptionsInterceptor`1.Invoke(IInvocation invocation)
   at SvnBridge.Proxies.RemotingInvocation.Proceed()
   at SvnBridge.Proxies.ProxyFactory.RemotingProxy.Invoke(IMessage msg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at SvnBridge.SourceControl.TFSSourceControlProvider.GetItemsWithoutProperties(Int32 version, String path, Recursion recursion)
   at SvnBridge.Handlers.PropFindHandler.GetItems(TFSSourceControlProvider sourceControlProvider, Int32 version, String path, Recursion recursion, Boolean loadPropertiesFromFile)
   at SvnBridge.Handlers.PropFindHandler.GetFolderInfo(TFSSourceControlProvider sourceControlProvider, String depth, String path, Nullable`1 version, Boolean loadPropertiesFromFile)
   at SvnBridge.Handlers.PropFindHandler.WriteBcResponse(TFSSourceControlProvider sourceControlProvider, String requestPath, String depthHeader, PropData data, Stream outputStream)
   at SvnBridge.Handlers.PropFindHandler.HandleProp(TFSSourceControlProvider sourceControlProvider, String requestPath, String depthHeader, String labelHeader, PropData data, Stream outputStream)
   at SvnBridge.Handlers.PropFindHandler.Handle(IHttpContext context, TFSSourceControlProvider sourceControlProvider)
   at SvnBridge.Handlers.RequestHandlerBase.Handle(IHttpContext context, IPathParser pathParser, NetworkCredential credentials)
   at SvnBridge.Net.HttpContextDispatcher.Dispatch(IHttpContext connection)
   at SvnBridge.Net.Listener.Process(TcpClient tcpClient)
   at SvnBridge.Net.Listener.Accept(IAsyncResult asyncResult)

May 16, 2012 at 8:35 AM

I believe that the most likely origin of this error is this part in SvnBridgeLibrary/SourceControl/TFSSourceControlProvider.cs GetLog():

                if (renamedItems.Count > 0)
                {
                    ItemMetaData[] oldItems = GetPreviousVersionOfItems(renamedItems.ToArray(), history.ChangeSetID);
                    var oldItemsById = new Dictionary<int, ItemMetaData>();
                    for (var i = 0; i < renamedItems.Count; i++)
                    {
                        if(oldItems[i] != null)
                            oldItemsById[renamedItems[i].ItemId] = oldItems[i];
                    }

Possibly the GetPreviousVersionOfItems() request ends up unsuccessful, returns an empty array, yet we then actively index this *empty* array via a loop variable derived from the *foreign* renamedItem size value (renamedItems.Count).

 

Now if this is in fact where the range exception occurs, then the question would be:

what kind of environment setup would cause an oldItems query for an existing amount of renamedItems to fail? (given this code and common sense, this is not really expected to happen)

Are you aware of any "interesting" renames in this repository directory?

 

To debug it, you could create a custom build of the SvnBridge project, start the resulting SvnBridge binary, then tray icon context menu "Debugger" item,

then choose existing Visual Studio SvnBridge build environment, then F5 (continue), then place breakpoint on GetLog() or more specifically also after the

if (renamedItems.Count > 0)

line.

Nov 9, 2013 at 6:39 PM
You were correct in your suspicion that the oldItems array comes back empty. I changed the for loop to:
for (var i = 0; i < oldItems.Count(); i++)
This seems to fix the issue but does anyone know what the ramifications of this are? It appears that any folder in my repository that has ever been renamed is broken (using TFS 2012).
Nov 11, 2013 at 3:00 PM
I have about as many ideas as you, but one thing that occurred to me:

in GetPreviousVersionOfItems():

While initial assignment of renamedItems will end up equal-sized compared to items (due to .Select() behaviour), the TFS08 fallback part sounds fishy:
that thingy might end up returning less items than what the items input is about (as opposed to the non-TFS08 conditional branch where this is not the case, since it's more symmetric).

Yet the GetPreviousVersionOfItems() user demands a same-index contract, which crashes hard in case of less result items than input size.

You'd have to debug it like I described above, I'm afraid.

Incidentally, that part is completely rewritten in my SvnBridge version.