While trying to work with URIs representing files,
I found that the (newer) nbfs: URI style does not
really work. E.g.
represents the file with path bar/baz in a
filesystem with system name /tmp/foo (i.e. a
Unfortunately when you make a java.net.URI out of
this and call getPath, you get
which is pretty much useless because you cannot
reconstruct the original URI from it.
I.e. escaping with '%' is a *syntactic* device and
cannot be used to safely store *semantic*
information in the URI. The above URI is
equivalent for all purposes to
which of course is not usable for getting a
Sorry to bring this up now, but I just now noticed
it. It is potentially a serious problem.
The new syntax was introduced in the 3.6 dev cycle to fix issue #31841.
Shoud I put something like '!' after filesystem part to be able to
distinguish either filesystem or resource part efter '%' decoding?
I think that if you extract just only path from your URI you can't
expect, that you'll be able to reconstruct original URI. For jar
protocol new URI
returns null. Also for old encoding you get null: new URI
("nbfs:QBtmpQBfoo/bar/baz").getPath () - so I think this isn't
regression at all.
Can you specify few asserts that must be satisfied ?
Priorirty decreased. If you still think that its potentionally
dangerous then please let me know.
The difference with the jar: and the nbfs: URIs is that in those
cases, if you decompose the URI using java.net.URI and then recreate
it, AFAIK you get back the same string - the path is null but the info
is encoded elsewhere. With the new URI syntax you get back something
different and unusable. Perhaps it's not a regression in practice,
since no old code could have been using the path for anything
important, but it's still incorrect IMHO.
Will try to supply a test case and suggest a fix when I have a moment.
Jesse, any ideas/suggestions how this should be fixed?
I will commit additional asserts to FileObjectTestHid.testGetURL. (The
current test is completely useless - it just tests that the URL is not
null! No wonder there are bugs in the implementation.)
Surprisingly, the added asserts pass for LocalFileSystemTest;
apparently FileObject.getURL now returns a file-protocol URL when it
can, which is the most important aspect of this bug for the build
system. (When did this change?)
On the other hand, XMLFileSystemTest and JarFileSystemTest fail as I
correct parent URI
The first URI is what you get by taking a child, getting its
java.net.URI, trimming the last path component from its path, and
recreating a parent URI using the same scheme and authority but the
truncated path. The second URI is the URI actually reported for the
parent. Note that the computed URI is nonsense: %2F in the child URI
has been unescaped by java.net.URI as it should be.
Note that while the new behavior of FileObject.getURL allows
LocalFileSystemTest to pass (since file: URIs behave properly), it is
however broken for MultiFileSystem2Test since using a file: URI for a
multi file object means that the URI cannot be used to find its parent
correct parent URI expected:<nbfs://nbhost/mfs2test/> but
Re. priority of this bug: P3 is OK with the build system team, so long
as we can be sure that URIs at least work correctly for local files
and JAR files for promo-D. However I am concerned that if the new
broken URL syntax is committed to the product in NB 3.6 that there
will be a backward compatibility issue when we fix the syntax for
promo-D. That is why I think it would be best to fix the bug now
before it is ever used in a public release.
Slight change: I am putting in a patch to URLMapper to return
jar-protocol URLs for JarFileSystem when requested via INTERNAL as
well as EXTERNAL. (Might as well avoid the proprietary URL protocol
- That breaks JarFileSystem.testForSpaces using
URLMapperTestInternalHidden, but the test was already broken using
- JarFileSystemTest.testGetURL now passes because URI.getPath() ==
null and I cut the test short in this case.
- XMLFileSystemTest.testGetURL is still broken as explained here.
- MultiFileSystem2Test.testGetURL is still broken; the child URL is a
file-protocol URL while the parent is a nbfs-protocol URL. I am not
sure if this violates the class Javadoc for URLMapper or not:
"For all methods, if the passed-in file object is the root folder of
some filesystem, then it is assumed that any valid file object in that
filesystem may also have a URL constructed for it by means of
appending the file object's resource path to the URL of the root folder."
I just reversed the test a bit, so that it first gets the parent URI,
then computes the child URI by appending the child's filename, then
uses URLMapper to try to get the child file object back from the
computed child URI. This is clearly permitted by URLMapper's class
Javadoc. (It is not clearly permitted to get the parent's URI by
removing the child's filename.)
But still MultiFileSystem2Test fails: the child URI is file-protocol,
and URLMapper.findFileObjects refuses to return the MultiFileObject of
the child (even though that MultiFileSystem is mounted in the repository).
So I recommend that URLMapper.findURL(MultiFileObject,INTERNAL) always
return a nbfs-protocol URL. I will try to make such a patch.
committed Up-To-Date 1.24
committed * Up-To-Date 1.106 openide/test/cfg-unit.xml
committed * Up-To-Date 1.26
re-evaluate please ...
No immediate harm done since no one uses this URL protocol for working
with real files AFAIK.
Reassigning to new module owner jskrivanek.
Not harmed anything since 2004.
NetBeans.org Migration: changing resolution from LATER to WONTFIX
Generally no longer used except for the system filesystem, for which e.g.
is usable, though it would be better style to have e.g.
Created attachment 92832 [details]
Start of patch
Attached patch does not work as is because hostnames cannot contain many characters:
java.lang.IllegalStateException: java.security.PrivilegedActionException: java.net.URISyntaxException: Expected closing bracket for IPv6 address at index 13: nbfs://[file:/space/src/nb/core-main/openide.filesystems/build/test/unit/work/o.o.f.F/ffdcefs-1/xfstest030/xfstest.xml]/
Using URLEncoder does not help since hostnames are too restricted:
new URI("nbfs", URLEncoder.encode("file:/tmp/foo.xml", "UTF-8"), "/whatever", null)
java.net.URISyntaxException: Illegal character in hostname at index 11: nbfs://file%3A%2Ftmp%2Ffoo.xml/whatever
Would need to use some custom encoding scheme, just like internationalized domain names do. Probably not worth the trouble.