SVNKit does not properly URLEncode URLs in outbound HTTP requests (SVNKit <-> Jetty)

I wish to re-raise SVNKIT-491.
I am running into issues connecting Atlassian Fisheye to SCM-Manager. Fisheye is throwing exceptions about spaces being in the path name of files within my SVN repo. I believe this can be reduced to just examing SVNKit (Fisheye side) and Jetty (SCM Manager side). The above mentioned ticket had other users coming to the same conclusion. SVNKit is not encoding URLs properly, and Jetty; being a simplier web server; is just rejecting the connection rather than handling it gracefully.

Hello Brendan,
could you provide more information regardng the issue?

  • Do you mean that the problems with SVNKit happen on the client side (i.e. ‘jsvn’ command line utility or Fisheye itself or any SVNKit-based SVN client) or with SVNKit on the server side (SCM-Manager uses ‘svnkit-dav’ under the hood, so there’s SVNKit as well)? If you’re not sure (e.g. you have SVNKit both on the server and on the client), please try various combinations (e.g. TortoiseSVN (or native SVN cli) + SCM-Manager and Fisheye+mod_dav_svn) to find that out.
  • What exactly error do you see and what URL are you using (I’m mostly interested where does the space occur in the URL)? What is the operation that fails?
  • If the problem happens on the client side, could you create a test repository with the problem reproducible like Richard Stephens did?
  • If Fisheye has the error in the logs, the logs probably could be helpful.

The more information you provide, the better it is; the most desirable is to have a test reproducible for us and you that would indicate that the problem is still present.

I can access files with spaces through the SCM Manager web front end, as well as through TortoiseSVN. The issue certainly appears to be with SVNKit on the client side (Fisheye).

Tue Jun 23 11:12:49 ACST 2020: Repository paused due to error com.cenqua.fisheye.rep.RepositoryClientException: org.apache.subversion.javahl.ClientException: svn: E175002: PROPFIND of '/scm/repo/alt/test/!svn/ver/4/this is a file with spaces.txt': 400 Illegal character SPACE= (<redacted address>) org.apache.subversion.javahl.ClientException: svn: E175002: PROPFIND of '/scm/repo/alt/test/!svn/ver/4/this is a file with spaces.txt': 400 Illegal character SPACE= (<redacted address>) org.tmatesoft.svn.core.SVNException: svn: E175002: PROPFIND of '/scm/repo/alt/test/!svn/ver/4/this is a file with spaces.txt': 400 Illegal character SPACE= (<redacted address>) org.tmatesoft.svn.core.SVNException: svn: E175002: PROPFIND of '/scm/repo/alt/test/!svn/ver/4/this is a file with spaces.txt': 400 Illegal character SPACE= (<redacted address>)

This error occurs after Fisheye has completed scanning all changesets, and begins to index changesets. I belive Fisheye is running on of the following commands when it fails:

svn info -R -r 4 http://<redacted>/scm/repo/alt/test/this%20is%20a%20file%20with%20spaces.txt@4
svn diff --summarize -r 3:4 http://<redacted>/scm/repo/alt/test/@4

Yes. I will attach. Above error is caused by changeset 4 in this repo. svn_test_repo.zip (22.0 KB)

I don’t have immediate access to the logs, but could probably hunt these down if they might add more insight than the error above from Fisheye.

I am seeing this problem with my fisheye and scm-manager svn repos. svnkit version is 1.10.1. It looks like this is an old issue. Is someone working to fix it? If not, is there a workaround? Atlassian is recommending using a native client instead of svnkit, but I don’t want to make big changes in my production environment until I understand the cause and is there are no other fixes. thank you.
from fisheye log:
"2022-04-13 10:00:59,838 WARN [InitPing3 test-xmp ] fisheye BaseRepositoryScanner-handleSlurpException - Problem processing revisions from repository test-xmp (test-xmp) due to class com.cenqua.fisheye.rep.RepositoryClientException - org.apache.subversion.javahl.ClientException: svn: E175002: PROPFIND of ‘/scm/repo/XSeries/iris_main/!svn/ver/3/MDApp/trunk/Defib-Monitor/Applications/MS Dot-Net Framework 2_0/dotnetfx.exe’: 400 Illegal character SPACE=

At the moment nobody is working on a work-around because I can’t reproduce the problem. Once I’m able to reproduce the problem, I can easily fix it.

What is suspicious is that both reports mention scm-manager. Is the problem reproducible with Apache mod_dav_svn with the same repository?

the problem is only evident using a jetty interface which is what scm-manager uses. we used to use teamforge which uses mod_dav_svn. the problem does not occur there.

If you have the means to zoom or the like, I can share my screen and we can look at logs or whatever to help you debug this.

Could you try ‘jsvn’ which is included into SVNKit distribution and could you compare the same command to native ‘svn’? I don’t know the exact command which fails but @BrendanK suggests it’s some kind of “svn diff --summarize”. It’s interesting whether one of the commands fail or both.

If you have no problem with mod_dav_svn, the problem is probably in ‘svnkit-dav’ (server-side SVNKit — a servlet which is an analog of mod_dav_svn). I’ll try to reproduce the problem with ‘svnkit-dav’. If I fail, I’ll ask you to share the screen and have a debug session.

from what I have learned, svnkit is used by Atlassian fisheye by default. I have verified with Atlassian support that my instance of fisheye is using svnkit for the svn client.

I downloaded svnkit from your site. and ran this command: ./jsvn diff --summarize -r 112:113 https://zzzzzz.zollmed.com:8443/scm/repo/THOR/thor_mp/@113
svn: E175002: PROPFIND of ‘/scm/repo/THOR/thor_mp/!svn/ver/113/apps/trunk/MP Patient Parms’: 400 Illegal character SPACE=

here is a regular svn command - svn diff --summarize -r 112:113 https:/zzzzzz.zollmed.com:8443/scm/repo/THOR/thor_mp/@113
A https://zzzzzz.zollmed.com:8443/scm/repo/THOR/thor_mp/apps/trunk/MP%20Patient%20Parms

Did this test help? Do you need more information?

Thanks for the test but so far it helps only partly. This test shows that it’s the client that has the problem. On the other hand you report that you never have problems with with mod_dav_svn, only with SCM Manager. So probably the problem is with the server (SCM Manager is based on ‘svnkit-dav’).

I’ve tried to create a server using ‘svnkit-dav’ (org.tmatesoft.svn.core.internal.server.dav.DAVServlet) but it works well with both native svn and jsvn, even for files with spaces.

Scm-manager is free. Why not setup a server of your own to test svnkit against it?
This is definitely a deficit in svnkit client. Atlassian recommends moving to a native svn client away from svnkit.

Hi Everyone! I have been debugging this with the Fisheye development and it is as @mcote has specified:

  • the issue is easy to reproduce using scm-manager (i was able to use a docker image) and an svn repo with spaces in the branch name
  • when breakpoints are used to control code path execution we can see that this issue occurs in tmate code when the PROPFIND is issued against the svn url

Please let me know if you need more details.

1 Like

Thanks everyone. I’ve finally managed to reproduce the problem with SCM Manager.
Here’re the intermediate results. The error happens when SVNKit sends request like this

REPORT /scm/repo/scmadmin/test/!svn/vcc/default HTTP/1.1
Host: localhost:8080
User-Agent: SVN/${project.compatibleSvnVersion} SVNKit/${project.buildVersion.baseVersion} (http://svnkit.com/) ${project.buildVersion.buildNumber}
Keep-Alive:
Connection: TE, Keep-Alive
TE: trailers
Authorization: Basic c2NtYWRtaW46c2NtYWRtaW4=
Content-Length: 400
Accept-Encoding: gzip
Content-Type: text/xml; charset="utf-8"
DAV: http://subversion.tigris.org/xmlns/dav/svn/depth
DAV: http://subversion.tigris.org/xmlns/dav/svn/mergeinfo
DAV: http://subversion.tigris.org/xmlns/dav/svn/log-revprops
Accept-Encoding: svndiff1;q=0.9,svndiff;q=0.8

and gets a response that is parsed with SAX Parser included into JVM (HTTPConnection#readData, HTTPConnection.java:886), and the SAX parser considers the response as invalid XML:

org.xml.sax.SAXException: svn: E175002: PROPFIND of '/scm/repo/scmadmin/test/!svn/ver/3/branches/branch with space': 400 Illegal character SPACE=  (http://localhost:8080)
org.tmatesoft.svn.core.SVNException: svn: E175002: PROPFIND of '/scm/repo/scmadmin/test/!svn/ver/3/branches/branch with space': 400 Illegal character SPACE=  (http://localhost:8080)
	at org.tmatesoft.svn.core.internal.io.dav.handlers.BasicDAVHandler.endElement(BasicDAVHandler.java:106)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:609)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1782)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2967)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
	at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
	at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)
	at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)
	at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
	at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
	at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
	at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.readData(HTTPConnection.java:898)
	at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.readData(HTTPConnection.java:863)
	at org.tmatesoft.svn.core.internal.io.dav.http.HTTPRequest.dispatch(HTTPRequest.java:220)
	at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:451)
	at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:352)
	at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:340)
	at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.performHttpRequest(DAVConnection.java:914)
	at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.doReport(DAVConnection.java:364)
	at org.tmatesoft.svn.core.internal.io.dav.DAVRepository.runReport(DAVRepository.java:1363)
	at org.tmatesoft.svn.core.internal.io.dav.DAVRepository.diff(DAVRepository.java:839)
	at org.tmatesoft.svn.core.internal.wc2.ng.SvnNgDiffSummarize.doDiffReposRepos(SvnNgDiffSummarize.java:273)
	at org.tmatesoft.svn.core.internal.wc2.ng.SvnNgDiffSummarize.doDiff(SvnNgDiffSummarize.java:86)
	at org.tmatesoft.svn.core.internal.wc2.ng.SvnNgDiffSummarize.run(SvnNgDiffSummarize.java:59)
	at org.tmatesoft.svn.core.internal.wc2.ng.SvnNgDiffSummarize.run(SvnNgDiffSummarize.java:23)
	at org.tmatesoft.svn.core.internal.wc2.ng.SvnNgOperationRunner.run(SvnNgOperationRunner.java:20)
	at org.tmatesoft.svn.core.internal.wc2.SvnOperationRunner.run(SvnOperationRunner.java:21)
	at org.tmatesoft.svn.core.wc2.SvnOperationFactory.run(SvnOperationFactory.java:1239)
	at org.tmatesoft.svn.core.wc2.SvnOperation.run(SvnOperation.java:294)
	at org.tmatesoft.svn.core.wc.SVNDiffClient.doDiffStatus(SVNDiffClient.java:3244)
	at org.tmatesoft.svn.core.wc.SVNDiffClient.doDiffStatus(SVNDiffClient.java:1559)
	at org.tmatesoft.svn.test.DiffTest.test(DiffTest.java:1203)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at com.intellij.junit4.JUnit45ClassesRequestBuilder$1$1$2$2.runChild(JUnit45ClassesRequestBuilder.java:82)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.tmatesoft.svn.core.SVNException: svn: E175002: PROPFIND of '/scm/repo/scmadmin/test/!svn/ver/3/branches/branch with space': 400 Illegal character SPACE=  (http://localhost:8080)
	at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.error(SVNErrorManager.java:70)
	at org.tmatesoft.svn.core.internal.wc.SVNErrorManager.error(SVNErrorManager.java:57)
	at org.tmatesoft.svn.core.internal.io.dav.DAVUtil.getResourceProperties(DAVUtil.java:79)
	at org.tmatesoft.svn.core.internal.io.dav.handlers.DAVEditorHandler.addNodeProperties(DAVEditorHandler.java:671)
	at org.tmatesoft.svn.core.internal.io.dav.handlers.DAVEditorHandler.endElement(DAVEditorHandler.java:495)
	at org.tmatesoft.svn.core.internal.io.dav.handlers.BasicDAVHandler.endElement(BasicDAVHandler.java:103)
	... 53 more

So probably the SCM Manager forms an HTTP response with invalid XML as the body. But native Subversion uses libexpat as an XML parsing library and libexpat doesn’t consider the response as invalid XML.

The response is

<?xml version="1.0" encoding="UTF-8"?>
<S:update-report xmlns:D="DAV:" xmlns:SD="http://subversion.tigris.org/xmlns/dav/" xmlns:S="svn:">
<S:target-revision rev="3"/>
<S:open-directory rev="1">
<D:checked-in>
<D:href>/scm/repo/scmadmin/test/!svn/ver/3/</D:href>
</D:checked-in>
<S:add-directory bc-url="/scm/repo/scmadmin/test/!svn/bc/3/branches" name="branches">
<D:checked-in>
<D:href>/scm/repo/scmadmin/test/!svn/ver/3/branches</D:href>
</D:checked-in>
<S:add-directory bc-url="/scm/repo/scmadmin/test/!svn/bc/3/branches/branch%20with%20space" name="branch with space">
<D:checked-in>
<D:href>/scm/repo/scmadmin/test/!svn/ver/3/branches/branch with space</D:href>
</D:checked-in>
<S:prop>
<D:version-name>3</D:version-name>
<D:creationdate>2022-04-15T15:38:11.796000Z</D:creationdate>
<D:creator-displayname>scmadmin</D:creator-displayname>
</S:prop>
</S:add-directory>
<S:prop>
<D:version-name>3</D:version-name>
<D:creationdate>2022-04-15T15:38:11.796000Z</D:creationdate>
<D:creator-displayname>scmadmin</D:creator-displayname>
</S:prop>
</S:add-directory>
<S:open-directory rev="1" name="trunk">
<D:checked-in>
<D:href>/scm/repo/scmadmin/test/!svn/ver/2/trunk</D:href>
</D:checked-in>
<S:open-file rev="1" name="file with space">
<D:checked-in>
<D:href>/scm/repo/scmadmin/test/!svn/ver/2/trunk/file with space</D:href>
</D:checked-in>
<S:txdelta>
U1ZOAQ==
</S:txdelta>
<S:fetch-file base-checksum="d41d8cd98f00b204e9800998ecf8427e"/>
<S:prop>
<SD:md5-checksum>5b4bd9815cdb17b8ceae19eb1810c34c</SD:md5-checksum>
<D:version-name>2</D:version-name>
<D:creationdate>2022-04-15T15:14:14.955000Z</D:creationdate>
<D:creator-displayname>scmadmin</D:creator-displayname>
</S:prop>
</S:open-file>
<S:prop>
<D:version-name>2</D:version-name>
<D:creationdate>2022-04-15T15:14:14.955000Z</D:creationdate>
<D:creator-displayname>scmadmin</D:creator-displayname>
</S:prop>
</S:open-directory>
<S:prop>
<D:version-name>3</D:version-name>
<D:creationdate>2022-04-15T15:38:11.796000Z</D:creationdate>
<D:creator-displayname>scmadmin</D:creator-displayname>
</S:prop>
</S:open-directory>
</S:update-report>

I tried 2 online XML validators, they consider the XML as valid.

I will continue the investigation…

Even though ‘svnkit-dav’ is a part of SCM Manager, it’s not ‘svnkit-dav’ to blame because when I try bare ‘svnkit-dav’ with the same repository, everything works fine with both native svn and jsvn.

        Server server = new Server(8000);

        ServletHandler handler = new ServletHandler();
        server.setHandler(handler);
        handler.addServletWithMapping(DAVServlet.class, "/*");

        ServletContextHandler servletContextHandler = new ServletContextHandler();
        servletContextHandler.setSessionHandler(new SessionHandler());
        servletContextHandler.setContextPath("/");
        handler.setHandler(servletContextHandler);

        DAVServlet servlet = new DAVServlet();
        ServletHolder servletHolder = new ServletHolder(servlet);
        servletHolder.setInitParameter("SVNPath", "/tmp/svn.repo");
        servletContextHandler.addServlet(servletHolder, "/*");

        server.start();
        server.join();

From this I so far conclude that the problem is with SAX Parser, but also the problem could be probably solved in SCM Manager.

On the other hand, when I feed that XML to the SAX Parser directly, it reports no error…

Probably, the problem is in double nesting of readData() call:

"main@1" prio=5 tid=0x1 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.readData(HTTPConnection.java:970)    <--- 2
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.readData(HTTPConnection.java:909)
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPRequest.dispatch(HTTPRequest.java:220)
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:497)
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:398)
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:386)
	  at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.performHttpRequest(DAVConnection.java:914)
	  at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.doPropfind(DAVConnection.java:147)
	  at org.tmatesoft.svn.core.internal.io.dav.DAVUtil.getProperties(DAVUtil.java:71)
	  at org.tmatesoft.svn.core.internal.io.dav.handlers.DAVEditorHandler.startElement(DAVEditorHandler.java:354)
	  at org.tmatesoft.svn.core.internal.io.dav.handlers.BasicDAVHandler.startElement(BasicDAVHandler.java:89)
	  at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
	  at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:374)
	  at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)
	  at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)
	  at com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:112)
	  at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)
	  at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)
	  at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)
	  at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
	  at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
	  at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.readData(HTTPConnection.java:949)   <--- 1
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.readData(HTTPConnection.java:909)
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPRequest.dispatch(HTTPRequest.java:220)
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:497)
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:398)
	  at org.tmatesoft.svn.core.internal.io.dav.http.HTTPConnection.request(HTTPConnection.java:386)
	  at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.performHttpRequest(DAVConnection.java:914)
	  at org.tmatesoft.svn.core.internal.io.dav.DAVConnection.doReport(DAVConnection.java:364)
	  at org.tmatesoft.svn.core.internal.io.dav.DAVRepository.runReport(DAVRepository.java:1363)
	  at org.tmatesoft.svn.core.internal.io.dav.DAVRepository.diff(DAVRepository.java:839)
	  at org.tmatesoft.svn.core.internal.wc2.ng.SvnNgDiffSummarize.doDiffReposRepos(SvnNgDiffSummarize.java:273)
	  at org.tmatesoft.svn.core.internal.wc2.ng.SvnNgDiffSummarize.doDiff(SvnNgDiffSummarize.java:86)
	  at org.tmatesoft.svn.core.internal.wc2.ng.SvnNgDiffSummarize.run(SvnNgDiffSummarize.java:59)
	  at org.tmatesoft.svn.core.internal.wc2.ng.SvnNgDiffSummarize.run(SvnNgDiffSummarize.java:23)
	  at org.tmatesoft.svn.core.internal.wc2.ng.SvnNgOperationRunner.run(SvnNgOperationRunner.java:20)
	  at org.tmatesoft.svn.core.internal.wc2.SvnOperationRunner.run(SvnOperationRunner.java:21)
	  at org.tmatesoft.svn.core.wc2.SvnOperationFactory.run(SvnOperationFactory.java:1239)
	  at org.tmatesoft.svn.core.wc2.SvnOperation.run(SvnOperation.java:294)
	  at org.tmatesoft.svn.core.wc.SVNDiffClient.doDiffStatus(SVNDiffClient.java:3244)
	  at org.tmatesoft.svn.core.wc.SVNDiffClient.doDiffStatus(SVNDiffClient.java:1559)
	  at org.tmatesoft.svn.test.DiffTest.test(DiffTest.java:1213)
	  at sun.reflect.NativeMethodAccessorImpl.invoke0(NativeMethodAccessorImpl.java:-1)
	  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	  at java.lang.reflect.Method.invoke(Method.java:498)
	  at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	  at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	  at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	  at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	  at com.intellij.junit4.JUnit45ClassesRequestBuilder$1$1$2$2.runChild(JUnit45ClassesRequestBuilder.java:82)
	  at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
	  at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	  at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	  at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	  at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	  at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	  at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	  at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
	  at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	  at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
	  at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
	  at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

It looks like nested calls are in general ok. While parsing XML upon some tags like <S:add-directory> PROPFIND requests are performed: both upon opening <S:add-directory> tags and upon closing </S:add-directory> tags. Upon opening <S:add-directory> tag, “bc-url=” attribute is used. Upon closing </S:add-directory> the URL is computed (incorrectly, without URL-encoding) and this causes problems.

For some reasons when using SVN server other than SCM server, when processing closing </S:add-directory> PROPFIND is not called, that’s why this bug flies under radar. When using SCM server it is called and the path (URL) is incorrect, resulting in HTTP 400 error code.

The only open question so far is the reason of this difference. The investigation is in progresss…

The difference between SCM Manager and svnkit-dav is like the following. SCM Manager:

<S:add-directory bc-url="/scm/repo/scmadmin/svn.repo/!svn/bc/4/branches/branch%20with%20spaces" name="branch with spaces">
<D:checked-in>
<D:href>/scm/repo/scmadmin/svn.repo/!svn/ver/4/branches/branch with spaces</D:href>
</D:checked-in>

svnkit-dav:

<S:add-directory bc-url="/!svn/bc/4/branches/branch%20with%20spaces" name="branch with spaces">
<D:checked-in>
<D:href>/!svn/ver/4/branches/branch%20with%20spaces</D:href>
</D:checked-in>

SCM Manager puts spaces into <D:href>, svnkit-dav doesn’t. But when performing a request to ‘bc-url’ both return %20-encoded values.

When looking into WebDAV protocol description, it states that

Note: ra_serf may not set the send-all attribute to the update-report.  It
      will instead take the returned D:checked-in href and do a pipelined
      PROPFIND / GET on that resource.

i.e. it assumes that one should be able to do GET or PROPFIND on the url in D:checked-in tag, but this is exactly what SVNKit client does and fails. I’ll also compare that to mod_dav_svn to see whether it’s not svnkit-dav which is wrong. Another open question is why native SVN doesn’t fail in that case.

Update:
mod_dav_svn also encodes <D:href>.

<S:add-directory name="directory with spaces" bc-url="/svn/repo/!svn/bc/81/trunk/directory%20with%20spaces">
<D:checked-in><D:href>/svn/repo/!svn/ver/81/trunk/directory%20with%20spaces</D:href></D:checked-in>

So I think, it’s better if the problem is fixed on SCM Manager side. The URL the XML retuns should allow GET and PROPFIND requests and this is not the case for SCM Manager and that’s where SVNKit client fails.

1 Like

thanks for all of the excellent work and assistance digging into this issue!
i checked the scm-manager issue tracker and found they already had a closed bug report which I added a comment to:

I also opened a new bug report since this issue can be replicated without using Fisheye (the reason they closed the bug): SCM Manager web server not handling spaces in name of files in SVN repo · Issue #2002 · scm-manager/scm-manager · GitHub