Skip to content

Literal "+" characters in file paths are incorrectly converted to spaces #1413

Description

@baxter-huntington

I discovered this small bug while attempting to enumerate the contents of a JPackage via dir when that package was provided by a JAR with a + in the file name.

import jpype
import jpype.imports

# Say com.foo.bar is provided by a JAR with the name foo-1.2.3-SNAPSHOT+456-g0123456789.jar`
# and com.foo.bar contains a class Baz
import com.foo.bar

print(dir(com.foo.bar))
# Output: []
# Expected: ['Baz']

Directly importing the class works just fine (i.e., from com.foo.bar import Baz). I believe that this is because this results in the direct instantiation of a JClass, rather than a JPackage, and JPackage.__dir__ invokes JPypePackageManager.collectContents, where this toURI re-encoding workaround is used:

 uri = new URI(
         uri.getScheme(),
         URLDecoder.decode(uri.getSchemeSpecificPart(), StandardCharsets.UTF_8),
         uri.getFragment()
 );

The documentation for URLDecoder.decode says:

The following rules are applied in the conversion:

  • The alphanumeric characters "a" through "z", "A" through "Z" and "0" through "9" remain the same.
  • The special characters ".", "-", "*", and "_" remain the same.
  • The plus sign "+" is converted into a space character " " .
  • A sequence of the form "%xy" will be treated as representing a byte where xy is the two-digit hexadecimal representation of the 8 bits. Then, all substrings that contain one or more of these byte sequences consecutively will be replaced by the character(s) whose encoding would result in those consecutive bytes. The encoding scheme used to decode these characters may be specified, or if unspecified, the default encoding of the platform will be used.

Thus, I believe the most targeted fix should just be URL-encoding "+" characters before the decoding workaround. I've linked a PR that does just that.

Thank you for this awesome project! 😄

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions