Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spaces in URI lead to an Exception #4

Closed
bgmf opened this issue Jan 22, 2016 · 6 comments
Closed

Spaces in URI lead to an Exception #4

bgmf opened this issue Jan 22, 2016 · 6 comments
Labels

Comments

@bgmf
Copy link

bgmf commented Jan 22, 2016

I know, that nothing has happened on this project for quite some time, but I stumbled accros it while struggeling with JCIFS.
Looks much cleaner, but there is a minor bug:
no.uis.nio.smb.SMBDirectoryStream#iterator
When you try to create a URI for a path containing spaces, like "Documents and Settings", the Stream crashes. It's easy to prevent by replacing

SMBPath p = new SMBPath(provider, file.getURL().toURI());

with something like

URI fileUri = new URI(file.getURL().toString().replace(" ", "%20"));
SMBPath p = new SMBPath(provider, fileUri);

Just if your are still interessted in this at all.

@maddingo maddingo added the bug label Jan 26, 2016
@maddingo
Copy link
Owner

The exception is thrown in the URI parser, not the SMBPath class. SMBPath expects a valid URI.

maddingo added a commit that referenced this issue Mar 17, 2016
maddingo added a commit that referenced this issue Mar 17, 2016
@bgmf
Copy link
Author

bgmf commented Jul 25, 2016

Sorry. It took some time for me to react, as well...

I just updated the repository and tried fetch the files and dirs from another machine and got the following result, by applying this JUnit "test":

@Test
    public void testSamba() {

        Logger.getLogger("").setLevel(Level.SEVERE);
        Config.registerSmbURLHandler();

        Path remotePath = null;
        try {
            NtlmAuthenticator.setDefault(new NtlmAuthenticator() {
                private NtlmPasswordAuthentication pa = new NtlmPasswordAuthentication("domain", "user", "password");
                @Override
                protected NtlmPasswordAuthentication getNtlmPasswordAuthentication() {
                    return pa;
                }
            });
            remotePath = Paths.get(new URI("smb://address/c$/"));
        } catch (URISyntaxException e1) {
            e1.printStackTrace();
        }

        ArrayList<String> fileNames = new ArrayList<>();
        try (DirectoryStream<Path> directoryStream = Files.newDirectoryStream(remotePath, new DirectoryStream.Filter<Path>() {
            @Override
            public boolean accept(Path entry) throws IOException {
                return !Files.isSymbolicLink(entry);
            }
        })) {
            for (Path path : directoryStream) {
                fileNames.add(path.toString());
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        System.out.println(fileNames);
    }

This is a stupid test, I know. It's just to demonstrate this result:

java.lang.RuntimeException: java.net.URISyntaxException: Illegal character in path at index 31: smb://address/c$/Android Studio/
    at no.uis.nio.smb.SMBDirectoryStream.iterator(SMBDirectoryStream.java:66)
    at no.uis.nio.smb.SambaTest.testSamba(SambaTest.java:53)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.net.URISyntaxException: Illegal character in path at index 31: smb://address/c$/Android Studio/
    at java.net.URI$Parser.fail(URI.java:2829)
    at java.net.URI$Parser.checkChars(URI.java:3002)
    at java.net.URI$Parser.parseHierarchical(URI.java:3086)
    at java.net.URI$Parser.parse(URI.java:3034)
    at java.net.URI.<init>(URI.java:595)
    at java.net.URL.toURI(URL.java:949)
    at no.uis.nio.smb.SMBDirectoryStream.iterator(SMBDirectoryStream.java:59)
    ... 24 more

When the SMBDirectoryStream is trying to iterate over all entries it may tries to construct URIs from SmbFile objects. The URLs inside it (#getUrl) may contains paths with spaces. When you try apply #toURI on these, an error will still occur.

see: SMBPath p = new SMBPath(provider, file.getURL().toURI());

I don't know, if I'm totallty wrong or not, but to me this is still broken.

@maddingo
Copy link
Owner

Thanks for the test case. Now I know what you mean. I check this out.

@maddingo maddingo reopened this Jul 25, 2016
maddingo added a commit that referenced this issue Jul 26, 2016
issue #4 accept file and directory names with spaces when traversing directories
@maddingo
Copy link
Owner

I uploaded version 1.1.7 to the Sonatype Releases Repo, it should be available on Maven Centraal soon. This version fixes your issue

@bgmf
Copy link
Author

bgmf commented Aug 2, 2016

Sorry for not reacting any earlier:
The test now works as expected. As long as as you don't try to query a directory with a space inside. If you try to get the directory stream of a path like smb://address/c$/Android%20Studio/, you will get another exception:

java.lang.RuntimeException: jcifs.smb.SmbException: The system cannot find the file specified.
    at no.uis.nio.smb.SMBDirectoryStream.iterator(SMBDirectoryStream.java:71)
    at no.uis.nio.smb.SambaTest.testSamba(SambaTest.java:56)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: jcifs.smb.SmbException: The system cannot find the file specified.
    at jcifs.smb.SmbTransport.checkStatus(SmbTransport.java:542)
    at jcifs.smb.SmbTransport.send(SmbTransport.java:619)
    at jcifs.smb.SmbSession.send(SmbSession.java:242)
    at jcifs.smb.SmbTree.send(SmbTree.java:111)
    at jcifs.smb.SmbFile.send(SmbFile.java:729)
    at jcifs.smb.SmbFile.doFindFirstNext(SmbFile.java:1931)
    at jcifs.smb.SmbFile.doEnum(SmbFile.java:1683)
    at jcifs.smb.SmbFile.listFiles(SmbFile.java:1660)
    at jcifs.smb.SmbFile.listFiles(SmbFile.java:1593)
    at no.uis.nio.smb.SMBDirectoryStream.iterator(SMBDirectoryStream.java:61)
    ... 24 more

It looks like, that now the library tries to look for the path with literally the %20 in it.
I played around a bit (I checked out the Git repo), but to be honest, I didn't come up with a solution for this ATM. I currently don't know where to look at. Maybe the SMBPath class?

@maddingo
Copy link
Owner

maddingo commented Aug 3, 2016

Thanks for reporting this error.
I am in the progress of moving the project to a new namespace in Maven Central. I already moved the project on github.
I will try to come up with a solution for the issue. I created a new issue #7 for this. Could you send me the code of your test case that fails? (either as pull request or as comment on issue #7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants